BZOJ3416: Poi2013 Take-out
2016-05-31 20:11
232 查看
题目大意:有n块砖,其中白色是黑色的k倍,求一个消除序列,满足以下条件:
每次消除k+1个砖,其中k块白色,1块黑色,并且这k+1块砖从开始到结束,中间不能路过已经消除过的砖
数据保证有解
这真是一个悲伤的故事,首先我把题想偏了,以为是只能每次取两边,写了一发WA了
然后网上没有题解,就很悲催的去看了波兰文的题解,里面一大堆百度翻译都翻译不出来的波兰语,就是如同什么“好数”“谈笑风声”之类的定义
幸亏我机智的看懂了他说的一部分话,才发现题意想错了,具体做法其实很简单
我们把这个序列的白色看成1,黑色看成-k,这样的话可以求一个前缀和,最近的a[i]相同的两个点之间的距离一定恰好为k+1
那我们就可以弄一个栈,按顺序把前缀和推进去,每当新进来的元素和之前栈中某一个元素权值相同,就把新来的元素连同两个元素之间的元素全部弹出,作为一次消除操作
这样的话倒序的消除序列一定是合法的,我就不证了
时间复杂度O(N)
然后还有一件事,POI官方题解时间复杂度O(NlogK)我也不知道是什么鬼,有兴趣可以去看看
POI2013波兰文题解 第82页
每次消除k+1个砖,其中k块白色,1块黑色,并且这k+1块砖从开始到结束,中间不能路过已经消除过的砖
数据保证有解
这真是一个悲伤的故事,首先我把题想偏了,以为是只能每次取两边,写了一发WA了
然后网上没有题解,就很悲催的去看了波兰文的题解,里面一大堆百度翻译都翻译不出来的波兰语,就是如同什么“好数”“谈笑风声”之类的定义
幸亏我机智的看懂了他说的一部分话,才发现题意想错了,具体做法其实很简单
我们把这个序列的白色看成1,黑色看成-k,这样的话可以求一个前缀和,最近的a[i]相同的两个点之间的距离一定恰好为k+1
那我们就可以弄一个栈,按顺序把前缀和推进去,每当新进来的元素和之前栈中某一个元素权值相同,就把新来的元素连同两个元素之间的元素全部弹出,作为一次消除操作
这样的话倒序的消除序列一定是合法的,我就不证了
时间复杂度O(N)
然后还有一件事,POI官方题解时间复杂度O(NlogK)我也不知道是什么鬼,有兴趣可以去看看
POI2013波兰文题解 第82页
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #define N 1000010 using namespace std; bool la[N<<1]; char s ; int a ; int q ,t; vector<int>ans ; int main() { int n,k; scanf("%d%d%s",&n,&k,s+1); int i,j,x,y; for(i=1;i<=n;i++) { if(s[i]=='c') a[i]=a[i-1]-k; else a[i]=a[i-1]+1; } int cnt=0; la =true; for(i=1;i<=n;i++) { a[i]+=n; if(la[a[i]]) { cnt++; for(j=t-k+1;j<=t;j++) { ans[cnt].push_back(q[j]); la[a[q[j]]]=false; } ans[cnt].push_back(i); t-=k; } else { t++;q[t]=i; la[a[i]]=true; } } for(i=cnt;i>=1;i--) { for(j=0;j<ans[i].size();j++) printf("%d ",ans[i][j]); puts(""); } }
相关文章推荐
- scala中使用protobuf
- Tcp/Ip通信协议
- SVM入门(五)线性分类器的求解——问题的描述Part2
- Middle-题目121:15. 3Sum
- CSS基础知识-四(边框样式、caption、表格居中、边框宽度和高度、id和class的区别、Div+CSS布局)
- Java多线程之线程创建和启动
- socket编程—select方法使用
- JAVA权重抽取
- 接口设计小结
- Middle-题目120:179. Largest Number
- MyEclipse快捷键
- 进程描述符task_struct
- ASP.NET MVC Model验证总结【转】
- 站立会议03(第二期)
- VMware 使用 NAT 模式联网问题
- Apache - AH00341
- Apache - AH00341
- 变量应用
- Middle-题目119:127. Word Ladder
- xshell项目服务器命令