NOIP2016 day2 t2蚯蚓
2017-04-03 09:53
411 查看
本蒟蒻这道题结结实实做了好多遍
开始没有想到好方法,就真的打了一个大根堆,成功TLE
后来经过大佬提醒,发现只要用单调队列就可以
STL不熟练,自己打了个手写的
首先解决每次蚯蚓变长的问题。显然,如果每次都让其他蚯蚓+q,那肯定会超时。可以类比懒惰标记(别问我为什么要这样类比,反正我最开始时是这样想的。好吧,没明白的就忽视这句话好了)。定义一个变量l,l的意思是如果某蚯蚓有幸从没有被切过,那么它当前将变长的长度。每次要切一条蚯蚓时,先让他+l,再切,得到x,y。然后l+=q。这是x和y都要-l。自己想想,可以想到这样做是正确的。
定义三个队列,一个存最开始的长度(当然是按照从大到小排序后的),设被切的那一个长度是x,那么一个存xp,一个存x(1-p)。自己动脑子想想,手动列一列算一算,容易证明(不要吐槽这个万恶的词语,自己证一证,真的很容易证明)三个队列都是单调的,即当前所有蚯蚓中的最大长度是三个单调队列front的最大值。
还有if(k%t==0)可能会被卡,所以我写了一个非常丑陋的防卡常,其实不写防卡常也是可以的
这样就可以了。复杂度O(m+n);
//但是跟大佬相比还是慢一些
开始没有想到好方法,就真的打了一个大根堆,成功TLE
后来经过大佬提醒,发现只要用单调队列就可以
STL不熟练,自己打了个手写的
首先解决每次蚯蚓变长的问题。显然,如果每次都让其他蚯蚓+q,那肯定会超时。可以类比懒惰标记(别问我为什么要这样类比,反正我最开始时是这样想的。好吧,没明白的就忽视这句话好了)。定义一个变量l,l的意思是如果某蚯蚓有幸从没有被切过,那么它当前将变长的长度。每次要切一条蚯蚓时,先让他+l,再切,得到x,y。然后l+=q。这是x和y都要-l。自己想想,可以想到这样做是正确的。
定义三个队列,一个存最开始的长度(当然是按照从大到小排序后的),设被切的那一个长度是x,那么一个存xp,一个存x(1-p)。自己动脑子想想,手动列一列算一算,容易证明(不要吐槽这个万恶的词语,自己证一证,真的很容易证明)三个队列都是单调的,即当前所有蚯蚓中的最大长度是三个单调队列front的最大值。
还有if(k%t==0)可能会被卡,所以我写了一个非常丑陋的防卡常,其实不写防卡常也是可以的
这样就可以了。复杂度O(m+n);
//但是跟大佬相比还是慢一些
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int inf=-0x7f; int read() { int f=1,p=0; char c=getchar(); while(c>'9'||c<'0') { if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9') { p=p*10+c-'0'; c=getchar(); } return f*p; } bool comp(int a,int b){return a>b;} int n,m,q,u,v,t; long long a[400010],z=1,zz=1,l; long long o[8000100],x=1,xx=1,h[8000100],c=1,cc=1; int check() { int t=1; if(a[z]<o[x])t=2; if(t==1&&a[z]<h[c])return 3; if(t==2&&o[x]<h[c])return 3; return t; } int main() { n=read(),m=read(); q=read(),u=read(); v=read(),t=read(); memset(a,inf,sizeof(a)); memset(o,inf,sizeof(o)); memset(h,inf,sizeof(h)); for(int i=1;i<=n;i++)a[i]=read(); sort(a+1,a+n+1,comp); for(int tt,i=1;i<=m;i++) { long long b; tt=check(); b=l,l+=q; if(tt==1)b+=a[z],++z; if(tt==2)b+=o[x],++x; if(tt==3)b+=h[c],++c; o[xx]=b*u/v-l,++xx; h[cc]=b-b*u/v-l,++cc; if(i%t==0)printf("%lld ",b); } printf("\n"); for(int tt,i=1;i<=m+n;i++) { long long b; tt=check(); if(tt==1)b=a[z],++z; if(tt==2)b=o[x],++x; if(tt==3)b=h[c],++c; if(i%t==0)printf("%lld ",b+l); } return 0; }
相关文章推荐
- 蚯蚓 NOIP2016 提高组 Day2 T2
- [luogu-2877]noip2016-day2-T2 蚯蚓 题解
- UOJ264 NOIP2016 day2 T2 蚯蚓(队列)
- noip2016 Day2 T2:蚯蚓 (归并)
- 【NOIP 2016 day2 T1 T2】组合数问题,蚯蚓——题解
- 2016 noip day2蚯蚓总结
- [NOIP2016]蚯蚓 D2 T2 队列
- UOJ 264 NOIP2016 DAY2 T2 浅谈队列单调性及辅助队列时间戳
- P4241【NOIP2016 DAY2】蚯蚓
- NOIP 2016提高组 Day2 蚯蚓
- 【NOIP2016提高组day2】蚯蚓
- NOIP2016 Day2 T2 天天爱跑步(树上差分)
- 【NOIP2016】蚯蚓 --队列模拟
- 全国信息学奥林匹克联赛(NOIP2011)复赛 提高组 day2 T2 聪明的质监员
- NOIP2016 T5 蚯蚓
- bzoj4721 [Noip2016]蚯蚓(模拟)
- 【NOIP2014 Day2 T2】寻找道路
- NOIP 2016 DAY2 T3题解
- Noip2011 Day2 T2 聪明的质监员 (二分+前缀和)
- NOIP 2016 Day1 T2 天天爱跑步