[BZOJ4105][Thu Summer Camp 2015]平方运算
2017-01-03 19:33
471 查看
题意
给定一个数列,有两种操作,询问一段区间[l,r]内的和或者对于i∈[l,r]的xi=xi 2%p类似于[bzoj3038]上帝造题的七分钟的思想
因为存在取模,所以xi变成xi 2%p一定会存在循环,又因为p给的比较特殊,循环的大小也比较小,所以可以对于处在循环中的数打标记,不处在循环中的数暴力。
#include <cstdio> #define N 100010 int n,m,p,A ,app ,op,l,r,ic ,ced ; struct bt{ int l,r,x[100],sz,bg,bic,sum,w; }T[N<<2]; inline void reaD(int &x){ char Ch=getchar();x=0; for(;Ch>'9'||Ch<'0';Ch=getchar()); for(;Ch>='0'&&Ch<='9';x=x*10+Ch-'0',Ch=getchar()); } inline void upd(int g){ T[g].sum=T[g<<1].sum+T[g<<1|1].sum; if(!T[g<<1].bic||!T[g<<1|1].bic)return; int i=T[g<<1].bg,j=T[g<<1|1].bg;T[g].bic=1; T[g].bg=1;T[g].sz=0; do{ T[g].x[++T[g].sz]=T[g<<1].x[i]+T[g<<1|1].x[j]; if((++i)>T[g<<1].sz)i=1; if((++j)>T[g<<1|1].sz)j=1; }while(i!=T[g<<1].bg||j!=T[g<<1|1].bg); } void buc(int g,int l){ T[g].bic=1; app[T[g].x[T[g].sz=1]=A[l]]=l;T[g].bg=1; while(l!=app[(T[g].x[T[g].sz]*T[g].x[T[g].sz])%p]){ app[(T[g].x[T[g].sz]*T[g].x[T[g].sz])%p]=l; T[g].x[++T[g].sz]=(T[g].x[T[g].sz-1]*T[g].x[T[g].sz-1])%p; } T[g].sum=T[g].x[T[g].bg]; } void build(int g,int l,int r){ T[g].l=l;T[g].r=r; if(l==r){ T[g].sum=A[l]; if(!ic[A[l]]) return; buc(g,l); return ; } int mid=l+r>>1; build(g<<1,l,mid);build(g<<1|1,mid+1,r); upd(g); } inline void down(int g){ if(T[g].w){ T[g<<1].sum=T[g<<1].x[++((T[g<<1].bg+=T[g].w-1)%=T[g<<1].sz)]; T[g<<1|1].sum=T[g<<1|1].x[++((T[g<<1|1].bg+=T[g].w-1)%=T[g<<1|1].sz)]; T[g<<1].w+=T[g].w;T[g<<1|1].w+=T[g].w; T[g].w=0; } } void update(int g,int l,int r){ if(T[g].l==l&&T[g].r==r){ if(T[g].bic){if((++T[g].bg)>T[g].sz)T[g].bg=1;T[g].sum=T[g].x[T[g].bg];T[g].w++;return;} if(l==r){ if(ic[(A[l]*=A[l])%=p])buc(g,l); T[g].sum=A[l]; return; } down(g); int mid=T[g].l+T[g].r>>1; update(g<<1,T[g].l,mid); update(g<<1|1,mid+1,T[g].r); upd(g); return; } down(g); int mid=T[g].l+T[g].r>>1; if(r<=mid) update(g<<1,l,r); else if(l>mid) update(g<<1|1,l,r); else update(g<<1,l,mid),update(g<<1|1,mid+1,r); upd(g); } int query(int g,int l,int r){ if(T[g].l==l&&T[g].r==r)return T[g].sum; down(g); int mid=T[g].l+T[g].r>>1; if(r<=mid) return query(g<<1,l,r); if(l>mid) return query(g<<1|1,l,r); return query(g<<1,l,mid)+query(g<<1|1,mid+1,r); } void dfs(int x){ if(ic[x]) return; int k=x; ced[x]=k;x=x*x%p; while(ced[x]!=k){ ced[x]=k; x=x*x%p; } int y=x;ic[x]=1;x=x*x%p; while(x!=y){ ic[x]=1; x=x*x%p; } } int w[20],wt; inline void Pt(int x){ if(!x){putchar(48);putchar('\n');return;} while(x)w[++wt]=x%10,x/=10; for(;wt;wt--)putchar(w[wt]+48);putchar('\n'); } int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); reaD(n);reaD(m);reaD(p); for(int i=0;i<p;i++) dfs(i); for(int i=1;i<=n;i++) reaD(A[i]); build(1,1,n); for(int i=1;i<=m;i++){ reaD(op);reaD(l);reaD(r); if(op==0) update(1,l,r); else Pt(query(1,l,r)); } return 0; }
相关文章推荐
- BZOJ 4105: [Thu Summer Camp 2015]平方运算
- bzoj4105: [Thu Summer Camp 2015]平方运算 线段树处理一类循环问题
- [Thu Summer Camp 2015] bzoj4105 平方运算 [线段树]
- bzoj:4105: [Thu Summer Camp 2015]平方运算
- BZOJ 4105: [Thu Summer Camp 2015]平方运算
- BZOJ4105 [Thu Summer Camp 2015]平方运算 【线段树】
- 4105: [Thu Summer Camp 2015]平方运算
- BZOJ 4104: [Thu Summer Camp 2015]解密运算
- BZOJ 4104 [Thu Summer Camp 2015]解密运算
- BZOJ 4103: [Thu Summer Camp 2015]异或运算
- 【bzoj4103】 【Thu Summer Camp 2015】【异或运算】【可持久化trie】
- BZOJ 4103 [Thu Summer Camp 2015]异或运算 可持久化Trie
- bzoj 4103: [Thu Summer Camp 2015]异或运算 可持久化trie
- 【BZOJ 4103】 [Thu Summer Camp 2015]异或运算 可持久化01Trie
- 【BZOJ 4104】 4104: [Thu Summer Camp 2015]解密运算 (智商)
- bzoj 4104: [Thu Summer Camp 2015]解密运算
- 【BZOJ4103】[Thu Summer Camp 2015]异或运算 可持久化Trie树
- 【bzoj4104】[Thu Summer Camp 2015]解密运算 乱搞
- 【bzoj4103】[Thu Summer Camp 2015]异或运算 可持久化Trie树
- [BZOJ4103][Thu Summer Camp 2015]异或运算 可持久化Trie树