You are given a simple task. Given a sequence A[i] with N numbers. You have to perform Q operations on the given sequence.
Here are the operations:
Note that no number in sequence ever will exceed 10^7.
The first line is a signer integer T which is the number of test cases.
For each test case, The first line contains two numbers N and Q (1 <= N, Q <= 100000) - the number of elements in sequence and the number of queries.
The second line contains N numbers - the elements of the sequence.
In next Q lines, each line contains an operation to be performed on the sequence.
For each test case and each query,print the answer in one line.
1 5 10 1 2 3 4 5 A 3 1 Q 1 3 R 5 2 4 A 1 1 Q 1 1 Q 1 2 Q 1 4 A 3 5 Q 5 5 Q 1 5
2 1 2 4 0 4Author: HUA, Yiwei
Source: ZOJ Monthly, October 2015
#include<bits/stdc++.h> using namespace std; const int Max=1e7; const int Maxn=1e6; int vis[Max+1000]; struct Tree { int num,lazy; }Tr[2*Maxn]; int init() { memset(vis,0,sizeof(vis)); vis[0]=vis[1]=1; int m=sqrt(Maxn); for(int i=2;i<=m;i++) { if(!vis[i]) { for(int j=i*i;j<=Maxn;j+=i) vis[j]=1; } } } int PushUp(int l,int r,int ind) //向下更新(主要更新区间的统计值) { if(Tr[ind<<1].lazy==Tr[ind<<1|1].lazy) { Tr[ind].lazy=Tr[ind<<1].lazy; } else { Tr[ind].lazy=0; } Tr[ind].num=Tr[ind<<1|1].num+Tr[ind<<1].num; } int PushDown(int l,int r,int ind) //向下更新(主要更新lazy(代表延迟操作)) { if(Tr[ind].lazy&&l!=r) { Tr[ind<<1].lazy=Tr[ind<<1|1].lazy=Tr[ind].lazy; if(Tr[ind].num) { int mid=(l+r)>>1; Tr[ind<<1].num=mid-l+1; Tr[ind<<1|1].num=r-mid; } else Tr[ind<<1|1].num=Tr[ind<<1].num=0; Tr[ind].lazy=0; } } int Build(int l,int r,int ind) { Tr[ind].lazy=0; Tr[ind].num=0; if(l==r) { scanf("%d",&Tr[ind].lazy); Tr[ind].num=(!vis[Tr[ind].lazy]); return 0; } int mid=(l+r)>>1; Build(l,mid,ind<<1); Build(mid+1,r,ind<<1|1); PushUp(l,r,ind); } int Add(int l,int r,int ind,int d,int t) { PushDown(l,r,ind); //变换之前向下更新(点的更新) if(l==t&&r==t) { Tr[ind].lazy+=d; Tr[ind].num=(!vis[Tr[ind].lazy]); return 0; } int mid=(l+r)>>1; if(t<=mid) Add(l,mid,ind<<1,d,t); else Add(mid+1,r,ind<<1|1,d,t); PushUp(l,r,ind); } int UpData(int l,int r,int ind,int L,int R,int d) { if(L>r||R<l) return 0; if(L<=l&&R>=r) { Tr[ind].lazy=d; Tr[ind].num=(!vis[d])*(r-l+1); return 0; } PushDown(l,r,ind); //区间的更新,变换之后向下更新 int mid=(l+r)>>1; if(L<=mid) UpData(l,mid,ind<<1,L,R,d); if(R>mid) UpData(mid+1,r,ind<<1|1,L,R,d); PushUp(l,r,ind); //最后进行向上更新 } int Query(int l,int r,int ind,int L,int R) { if(l>R||r<L) return 0; PushDown(l,r,ind); if(L<=l&&R>=r) { return Tr[ind].num; } int mid=(l+r)>>1; int sum=0; if(L<=mid) { sum+=Query(l,mid,ind<<1,L,R); } if(R>mid) { sum+=Query(mid+1,r,ind<<1|1,L,R); } PushUp(l,r,ind); return sum; } int main() { int T,n,q,l,r,d,t; char s[10]; init(); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q); Build(1,n,1); while(q--) { scanf("%s",s); if(s[0]=='A') { scanf("%d%d",&d,&t);//a[t]+d; Add(1,n,1,d,t); } if(s[0]=='Q') { scanf("%d%d",&l,&r); printf("%d\n",Query(1,n,1,l,r)); } if(s[0]=='R') { scanf("%d%d%d",&d,&l,&r); UpData(1,n,1,l,r,d); } } } }