题目链接:点击查看

题目大意:给出n个数列,每行放一个,现在指定一个宽度w,满足w不小于n个数列中最长的那个数列的长度,现在可以将n个数列都放入到一个n*w的矩形之中,每个数列可以在各自的行内左右移动,现在问对于每一列i,求出权值和的最大值,注意,若一个数列的长度小于w,那么其余的位置都用0补齐

题目分析:题目还是比较好懂的,因为给出的图片以及样例算是比较友好的了,看看图片就知道答案是怎么来的了。。读懂题目之后相当于一个中等难度偏下的模拟,我们只需要照做就好了

具体实现方法就是在输入的时候,对于每个数字当前的位置记录一下可贡献的区间,也就是通过移动可到达的最左和最后的位置,最左边的答案用in数组储存,最右边的答案用out数组储存,记录好后开始模拟,我们可以使用一个优先队列获得区间中的最大值,最外层的for枚举的是1~w的列的下标,内层for枚举的是1~n的行的下标,每次更新时将in数组内的数扔进去,将out数组内的数删掉,之后就可以直接得到答案了

不过上述方法的时间复杂度是n*w*logw级别的,在这个题目中是不可行的,所以我们必须想办法优化一下,而且在优先队列中也不支持随机访问和随机删除,所以我们可以用multiset来代替优先队列,每次插入也是logn级别的,而且可以支持find函数查找某个值的位置,以及搭配erase函数删除掉某个特定的值,刚好满足上面的操作了

至于优化的话,我们其实每次不必枚举到1~n,因为1~n的每一行在特定的第i列下,绝大部分都是对答案没有贡献的,也就是in数组和out数组在当前列的贡献为0,这样的话我们就可以将in和out数组的下标用列来表示,并将其设置为vector容器,这样就能每次只需要遍历in[i].size()+out[i].size()个变量了,从O(n)下降到了O(in[i].size()+out[i].size())了,因为题目保证了数组的总长度小于等于1e6,所以我们就完美的将n*w*logw的时间复杂度下降到了w*logw了,也就可以解决这个问题了

这个题目主要还是练习了multiset的使用吧,有一说一,确实蛮好用的,关于multiset我们需要注意一下,若我们要取得最后那个数,应该调用rbegin()而不是end()函数,因为end函数返回的是超尾,如果实在想用end的话可以改成end()-1,所以我们还是直接用rbegin()调用最后一个元素就好了

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e6+100;struct Node
{int val,pos;Node(int VAL,int POS){val=VAL;pos=POS;}
};//保存权值和位置(行)multiset<LL>st[N];//st[行]vector<Node>in[N],out[N];//in[列] out[列]LL ans[N];//ans[列]int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int n,w;scanf("%d%d",&n,&w);for(int i=1;i<=n;i++){int len;scanf("%d",&len);if(len<w)//空白地方可以补0 {in[1].push_back(Node(0,i));out[w-len].push_back(Node(0,i));in[len+1].push_back(Node(0,i));out[w].push_back(Node(0,i));}for(int j=1;j<=len;j++)//维护in数组和out数组{int num;scanf("%d",&num);in[j].push_back(Node(num,i));out[w-len+j].push_back(Node(num,i));}}for(int i=1;i<=w;i++)//枚举列数 st[行数]{ans[i]=ans[i-1];//因为每次答案可以在前置答案的基础上操作,避免了多余的操作for(int j=0;j<in[i].size();j++)//枚举行数 ans[列数]{int pos=in[i][j].pos;//行 int val=in[i][j].val;//值 if(st[pos].size())//如果存在区间最大值,则减去ans[i]-=*st[pos].rbegin();st[pos].insert(val);//更新区间最大值(插入一个值)ans[i]+=*st[pos].rbegin();//再加上区间最大值}for(int j=0;j<out[i-1].size();j++)//注意这里要用out[i-1]来维护ans[i]{int pos=out[i-1][j].pos;//行 int val=out[i-1][j].val;//值     ans[i]-=*st[pos].rbegin();//因为每个out前面必定对应着一个in,所以必定存在区间最大值,直接减去st[pos].erase(st[pos].find(val));//更新区间最大值(删除一个值)if(st[pos].size())//如果删除后还存在区间最大值的话,直接加上ans[i]+=*st[pos].rbegin();}}for(int i=1;i<=w;i++)printf("%lld ",ans[i]);return 0;
}

CodeForces - 1208E Let Them Slide(模拟+multiset)相关推荐

  1. trie树 Codeforces Round #367 D Vasiliy's Multiset

    1 // trie树 Codeforces Round #367 D Vasiliy's Multiset 2 // 题意:给一个集合,初始有0,+表示添加元素,-去除元素,?询问集合里面与x异或最大 ...

  2. CodeForces 1463 C. Busy Robot 模拟

    CodeForces 1463 C. Busy Robot 模拟 题目大意: 有一个一维坐标轴,在最初时刻有个机器人位于坐标 0 0 0 位置,有 n n n 个命令,对于每一个命令在 t i t_i ...

  3. BZOJ 3836 Codeforces 280D k-Maximum Subsequence Sum (模拟费用流、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=3836 (Codeforces) http://codeforces.com ...

  4. 【CodeForces Round #550】A-F | 模拟 | 贪心 | 高精 | BFS | 二分图 | E

    今年怎么没有愚人节比赛了   CF你看看人家洛谷   唉鸭原来那边还没到愚人节呢- 愚人节比赛还是有的,在今晚 qwq [CodeForces 1144   A-F] Tags:模拟 贪心 BFS 高 ...

  5. CodeForces - 1328F Make k Equal(模拟)

    题目链接:点击查看 题目大意:给出一个数列 a ,现在有两种操作: 找到一个最小值,使其值加一 找到一个最大值,使其值减一 注意这里找到一个最值进行的操作,是针对最值不唯一的情况,题目问至少需要进行多 ...

  6. CodeForces - 1321C Remove Adjacent(贪心+模拟)

    题目链接:点击查看 题目大意:给出一个长度不超过100且只包含小写字母的字符串,现在规定,如果某个位置 i 的相邻位置存在着当前位置所代表字母的前一个字母,即 i - 1 和 i + 1 中存在着 a ...

  7. CodeForces - 546C Soldier and Cards(模拟)

    题目链接:点击查看 题目大意:两个人在玩游戏,初始时两个人分别有一定数量的牌,牌面的大小一定是互不相同的,游戏规则如下: 每次两个人同时从自己牌堆的最顶端取出一张牌,我们可以记做a和b,比较一下其大小 ...

  8. CodeForces - 224C. Bracket Sequence (栈模拟)简单做法

    A bracket sequence is a string, containing only characters "(", ")", "[&quo ...

  9. CodeForces - 500A-New Year Transportation(模拟)

    New Year is coming in Line World! In this world, there are n cells numbered by integers from 1 to n, ...

最新文章

  1. java 锁_Java 锁之我见
  2. Yii2使用Cookie的注意事项
  3. 对话国际农民丰收节贸易会-林育庆:菲律宾谋定中国农业
  4. C语言函数调用的原理
  5. 资源推荐—HTML5精品资源
  6. Spring 框架基础(02):Bean的生命周期,作用域,装配总结
  7. 拥抱 Elasticsearch:给 TiDB 插上全文检索的翅膀
  8. C++之实现优先队列
  9. 485有时候从机接收指令没反应_多动症儿童反应慢好几拍?神经递质释放速度太慢就会出现这种问题!科学训练高效提升孩子反应力!...
  10. C# 同一应用程序域不同线程之间的参数传递方式
  11. php连接mysql MariaDB_PHP+MariaDB数据库操作基本技巧
  12. 【数据分析】《深入浅出统计学》要点总结
  13. c语言课程设计实训主要目的,《C语言课程设计实验大纲.doc
  14. 基于netty实现gps jtt808协议接入
  15. java自学笔记(4)-Stanford CS106A 弹球动画 20.9.9
  16. ThinkPad笔记本如何重装系统
  17. java.lang.SecurityException: getDeviceId: The user 10158 does not meet the requirements to access de
  18. 无盘系统对服务器的要求,无盘服务器配置要求高?两千的主机就能带100台客户机你信吗?-服务器设置...
  19. 如何找到google主题的壁纸
  20. HTML5+CSS3小实例:黏性小球loading动画

热门文章

  1. dubbo每次都要连zookeeper?
  2. 为什么任何对象都可以实现锁
  3. 微服务架构的实施现状
  4. 商品评价 - 实现分页
  5. 工程和模块的关系以及继承和依赖的概念
  6. ES6新特性之修饰器
  7. Calendar类介绍_获取对象的方式
  8. 图的最短路径(一级)
  9. php开启mysqlnd,如何启用mysqlnd的PHP?
  10. mongodb java连接 集群_java连接mongodb集群