Prime Query
Time Limit: 1 Second
Memory Limit: 196608 KB
You are given a simple task. Given a sequence A[i] with N
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]
Note that no number in sequence ever will exceed 10^7.
Input
The first line is a signer integer T
For each test case, The first line contains two numbers N and Q (1 <= N, Q
The second line contains N
In next Q
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;
}