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:
- A v l, add the value v to element with index l.(1<=V<=1000)
- R a l r, replace all the elements of sequence with index i(l<=i<= r) with a(1<=a<=10^6) .
- Q l r, print the number of elements with index i(l<=i<=r) and A[i] is a prime number
Note that no number in sequence ever will exceed 10^7.
Input
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.
Output
For each test case and each query,print the answer in one line.
Sample Input
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
Sample Output
2 1 2 4 04
题目大意:一个序列,n个数,m个操作,A表示第x个位置的数上边加y,R x y z,表示x到y区间内的数变成z,Q表示查询x y,区间内素数的个数
ac代码
<pre name="code" class="cpp">#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<iostream> #define LL long long using namespace std; bool isp[1000005]; int p[1000005],top; struct s { int sum,cover,num; }node[100005<<2]; void init() { top=0; memset(isp,true,sizeof(isp)); for(int i=2;i<1000005;i++) { if(isp[i]) p[top++]=i; for(int j=0;j<top&&(LL)i*p[j]<1000005;j++) { isp[i*p[j]]=false; if(!i%p[j]) break; } } } void pushup(int tr) { node[tr].sum=node[tr<<1].sum+node[tr<<1|1].sum; } void pushdown(int tr,int m) { if(node[tr].cover) { node[tr<<1].cover=node[tr].cover; node[tr<<1|1].cover=node[tr].cover; node[tr<<1].sum=(m-(m>>1))*isp[node[tr].cover]; node[tr<<1|1].sum=(m>>1)*isp[node[tr].cover]; node[tr<<1].num=node[tr].cover; node[tr<<1|1].num=node[tr].cover; node[tr].cover=0; } } void build(int l,int r,int tr) { node[tr].cover=0; if(l==r) { scanf("%d",&node[tr].num); node[tr].sum=isp[node[tr].num]; return; } int mid=(l+r)>>1; build(l,mid,tr<<1); build(mid+1,r,tr<<1|1); pushup(tr); } int ISP(int val)//快速判断是不是素数 { if((val&1)==0) return 0; int num=val; for(int i=0;i<top&&(LL)p[i]*p[i]<=val;i++) { while(val%p[i]==0) { val/=p[i]; } } return num==val; } void add(int pos,int val,int l,int r,int tr) { if(l==r) { node[tr].num+=val; node[tr].sum=ISP(node[tr].num); return; } pushdown(tr,r-l+1); int mid=(l+r)>>1; if(pos<=mid) add(pos,val,l,mid,tr<<1); else add(pos,val,mid+1,r,tr<<1|1); pushup(tr); } void update(int L,int R,int val,int l,int r,int tr) { if(L<=l&&r<=R) { node[tr].num=val; node[tr].cover=val; node[tr].sum=(r-l+1)*isp[val]; return; } pushdown(tr,r-l+1); int mid=(l+r)>>1; if(L<=mid) update(L,R,val,l,mid,tr<<1); if(R>mid) update(L,R,val,mid+1,r,tr<<1|1); pushup(tr); } int query(int L,int R,int l,int r,int tr) { if(L<=l&&r<=R) { return node[tr].sum; } pushdown(tr,r-l+1); int mid=(l+r)>>1; /*if(R<=mid) return query(L,R,l,mid,tr<<1); else if(L>mid) return query(L,R,mid+1,r,tr<<1|1); else return query(L,mid,l,mid,tr<<1)+query(mid+1,R,mid+1,r,tr<<1|1);*/ int a,b; a=0; b=0; if(L<=mid) a=query(L,R,l,mid,tr<<1); if(R>mid) b=query(L,R,mid+1,r,tr<<1|1); return a+b; } char op[10]; int main() { init(); int t; scanf("%d",&t); while(t--) { int n,q; scanf("%d%d",&n,&q); build(1,n,1); while(q--) { scanf("%s",op); if(op[0]=='A') { int x,y; scanf("%d%d",&x,&y); add(y,x,1,n,1); } else if(op[0]=='R') { int x,y,z; scanf("%d%d%d",&x,&y,&z); update(y,z,x,1,n,1); } else if(op[0]=='Q') { int x,y; scanf("%d%d",&x,&y); //scanf("%d%d",&x,&y); printf("%d\n",query(x,y,1,n,1)); } } } return 0; }