BZOJ3827 : [Poi2014]Around the world
2015-01-08 20:53
253 查看
把环倍长,破环成链
设f[i]表示i一次性能飞达的最右边的点,因为f[]单调递增,所以可以$O(n)$求出
这样就形成了一个树结构,对于每个节点,在其到根节点路径上二分出深度最大的点,使得其飞过一圈
常数优化:
注意到答案只有两种,所以可以进行最优性剪枝
内存优化:
只需要开3个200W的数组即可,分别表示相邻两站的距离、f[i]、存该点到根节点路径上所有点的栈
对于树结构的存储,注意到f[]单调递增,所以我们可以求出c[i]表示父亲为i的点的开始的位置
在DFS时,如果这个点第一次走到,那么它下一步就走向c[i],否则走向++c[i]
对于这个数组中的每个数,可以拆成两半,各11位,分别放进f[i]和b[i]的后11位中
设f[i]表示i一次性能飞达的最右边的点,因为f[]单调递增,所以可以$O(n)$求出
这样就形成了一个树结构,对于每个节点,在其到根节点路径上二分出深度最大的点,使得其飞过一圈
常数优化:
注意到答案只有两种,所以可以进行最优性剪枝
内存优化:
只需要开3个200W的数组即可,分别表示相邻两站的距离、f[i]、存该点到根节点路径上所有点的栈
对于树结构的存储,注意到f[]单调递增,所以我们可以求出c[i]表示父亲为i的点的开始的位置
在DFS时,如果这个点第一次走到,那么它下一步就走向c[i],否则走向++c[i]
对于这个数组中的每个数,可以拆成两半,各11位,分别放进f[i]和b[i]的后11位中
#include<cstdio> const int N=2000010,B=2097151; inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} int n,m,i,j,d,x,lim,ans,t,k,l,r,u,mid;unsigned int a ,b ,f ; inline void set(int x){(f[x]&=B)|=(i&2047)<<21,(b[x]&=B)|=i>>11<<21;} inline void cal(int x){ if(!k){ l=1,r=t-1; while(l<=r){ mid=(l+r)>>1; if((b[mid]&B)>=x)l=(u=mid)+1;else r=mid-1; } ans=t-u,k=1; }else{ if(t>ans&&(b[t-ans]&B)<x)k=2; if(t+1>ans&&(b[t-ans+1]&B)>=x)ans--,k=2; } } int main(){ read(n),read(m); for(i=1;i<=n;i++){ read(x);a[i]=a[i+n]=x; if(lim<x)lim=x; } while(m--){ read(d); if(d<lim){puts("NIE");continue;} for(j=i=1;i<=n*2;i++){ while(j<n*2&&d>=a[j])d-=a[j++]; f[i]=j; d+=a[i]; b[i]=0; } k=f[b[t=1]=n*2]=0; for(i=n*2-1;i;i--)set(f[i]&B); while(t){ x=b[t]&B; if((f[b[t+1]&B]&B)!=x){ if(x<=n)cal(x+n); if(k==2)break; i=(b[x]>>21<<11)|(f[x]>>21); }else{ i=(b[t+1]&B)+1; if((f[i]&B)!=x)i=0; } if(i)++t,b[t]=(b[t]>>21<<21)|i;else t--; } printf("%d\n",ans); } return 0; }
相关文章推荐
- 【BZOJ3827】[Poi2014]Around the world【尺取法】【并查集】
- BZOJ3827[Poi2014] Around the world
- BZOJ3827: [Poi2014]Around the world
- bzoj3827:[Poi2014]Around the world
- [POI2014]Around the world
- CHILDBIRTH TRADITIONS AROUND THE WORLD: CHINA
- Around the World in Eighty Days 19/201
- BNU-52305-Around the World(四川省赛H题)
- bzoj1748 [Usaco2005 open]Around the world 环球飞行
- 2016 四川省赛 H AroundtheWorld(BEST定理)
- 2016年四川省赛H题 Around the World(BEST定理||树形dp)
- Write the code.Change the world.---WWDC2014
- Ganymede Around the world中我的名字
- Around the World in Eighty Days 5/201
- ICPC-CAMP day1 D.Around the world
- 2016弱校联盟十一专场10.2——Around the World
- 2016 四川省赛 Around the World
- 12 Programming Languages in the Modern Web/Mobile World of 2014
- 2016弱校联盟十一专场10.2---Around the World(深搜+组合数、逆元)
- Around the World in 60 Days: Getting Deep Speech to Work in Mandarin