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 0 4
// 被这题的输入输出坑了一下午 最后几分钟才A了 没话说了。。
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <queue> #include <map> using namespace std; const int maxn=100000+10; const int inf=(1<<30); int arr[maxn],ans=0; int prime[10000010]; bool vis[10000010]; char s[1000000]; void prim() { memset(prime,0,sizeof(prime)); memset(vis,0,sizeof(vis)); for(int i=2;i<=10000005;i++) { if(!vis[i]) { prime[i]=1; for(int k=i*2;k<=10000005;k+=i) vis[k]=1; } } } struct Node { int l,r; int num,flag; int val; int mid() { return (l+r)/2; } }tree[maxn*6]; void Buildtree(int rt,int l,int r) { tree[rt].l=l; tree[rt].r=r; tree[rt].num=tree[rt].flag=0; if(l!=r) { Buildtree(2*rt,l,(l+r)/2); Buildtree(2*rt+1,(l+r)/2+1,r); tree[rt].num=tree[2*rt].num+tree[2*rt+1].num; } else { tree[rt].val=arr[tree[rt].l]; if(prime[tree[rt].val]) tree[rt].num=1; else tree[rt].num=0; } } void Pushdown(int rt) { tree[2*rt].val=tree[2*rt+1].val=tree[rt].val; if(prime[tree[rt].val]) { tree[2*rt].num=(tree[2*rt].r-tree[2*rt].l+1); tree[2*rt+1].num=(tree[2*rt+1].r-tree[2*rt+1].l+1); } else { tree[2*rt].num=0; tree[2*rt+1].num=0; } tree[2*rt].flag=tree[2*rt+1].flag=1; tree[rt].flag=0; } void Pushup(int rt) { tree[rt].num=tree[2*rt].num+tree[2*rt+1].num; } void Update(int rt,int val,int k) { if(tree[rt].l==tree[rt].r&&tree[rt].l==k) { tree[rt].val+=val; if(prime[tree[rt].val]) tree[rt].num=1; else tree[rt].num=0; return; } if(tree[rt].flag)Pushdown(rt); if(k<=tree[rt].mid()) Update(2*rt,val,k); else Update(2*rt+1,val,k); Pushup(rt); } void Update_1(int rt,int l,int r,int val) { if(tree[rt].l==l&&tree[rt].r==r) { tree[rt].val=val; if(prime[tree[rt].val]) tree[rt].num=(r-l+1); else tree[rt].num=0; tree[rt].flag=1; return; } if(tree[rt].flag)Pushdown(rt); if(r<=tree[rt].mid()) Update_1(2*rt,l,r,val); else if(l>tree[rt].mid()) Update_1(2*rt+1,l,r,val); else { Update_1(2*rt,l,tree[rt].mid(),val); Update_1(2*rt+1,tree[rt].mid()+1,r,val); } Pushup(rt); } void Query(int rt,int l,int r) { if(tree[rt].l==l&&tree[rt].r==r) { ans+=tree[rt].num; return; } if(tree[rt].flag)Pushdown(rt); if(r<=tree[rt].mid()) Query(2*rt,l,r); else if(l>tree[rt].mid()) Query(2*rt+1,l,r); else { Query(2*rt,l,tree[rt].mid()); Query(2*rt+1,tree[rt].mid()+1,r); } } int main() { int t; prim(); scanf("%d",&t); while(t--) { int n,m; char c[1000]; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",arr+i); Buildtree(1,1,n); getchar(); while(m--) { scanf("%s",c); int i=0; for(i=0;c[i]!='\0';i++) if(c[i]>='A'&&c[i]<='Z') break; if(c[i]=='A') { int val,index; scanf("%d%d",&val,&index); Update(1,val,index); } else if(c[i]=='Q') { ans=0; int l,r; scanf("%d%d",&l,&r); Query(1,l,r); printf("%d\n",ans); } else if(c[i]=='R') { int val,l,r; scanf("%d%d%d",&val,&l,&r); Update_1(1,l,r,val); } } } return 0; }