bzoj2054疯狂的馒头——线段树
中文题面,一排有n个馒头,用刷子把整个连续的区间刷成一种颜色。因为颜色会覆盖掉之前的。所以我们可以用线段树来反着处理。如果这段区间之前刷到过就不要再遍历进去了,因为这次已经被上次刷的颜色给覆盖了。最后遍历线段树到叶子节点,输出最后的值就行了。
#include<bits/stdc++.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid int m = (l + r) >> 1 const int M = 1e6+10; int sum[M<<2]; void pushup(int rt){ sum[rt]=sum[rt<<1]&&sum[rt<<1|1]; } void update(int p,int x,int y,int l,int r,int rt){ if(sum[rt]){ return ; } if(l==r) { sum[rt]=p; return; } mid; if(x<=m) update(p,x,y,lson); if(y>m) update(p,x,y,rson); pushup(rt); } void pr(int l,int r,int rt) { if(l==r) { printf("%d\n",sum[rt]); return; } mid; pr(lson); pr(rson); } int main() { int n,m,p,q; scanf("%d%d%d%d",&n,&m,&p,&q); for(int i=m;i>=1;i--) { int lll,rrr; lll=((i*p+q)%n)+1; rrr=((i*q+p)%n)+1; //cout<<l<<" "<<r<<endl; if(rrr<lll) { int t=rrr; rrr=lll; lll=t; } update(i,lll,rrr,1,n,1); } pr(1,n,1); return 0; }