Prime Query
Time Limit: 5 Seconds Memory Limit: 196608 KB
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
Author: HUA, Yiwei
Source: ZOJ Monthly, October 2015
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define read(x,y) scanf("%d%d",&x,&y)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define lrt int l,int r,int rt
/*
题目大意:线段树基本套路,
区间整体修改,单点更新,没什么特别的。
先预处理素数,
这里本人踩了个坑,,,
筛法时j从i*i开始是有条件的。。。注意数据范围。
懒惰标记设定为要修改成的那个值,其余的都是基础训练了。
*/
const int maxn =1e6+5;
///素数筛法
int vis[maxn];
///数据域部分
int n,m,t;
int x,y,z;
int a[maxn];
char s[5];
///线段树
int lazy[maxn<<2],sum[maxn<<2],tree[maxn<<2];///tree代表数据区间和,sum代表答案区间和
void pushup(lrt)
{
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(lrt)
{
if(l==r) return;
int mid=l+r>>1;
if(lazy[rt])///懒惰标记记录了区间修改值
{
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
tree[rt<<1]=(mid-l+1)*lazy[rt];
tree[rt<<1|1]=(r-mid)*lazy[rt];
sum[rt<<1]=(mid-l+1)*vis[lazy[rt]];
sum[rt<<1|1]=(r-mid)*vis[lazy[rt]];
lazy[rt]=0;
}
}
void build(lrt)
{
lazy[rt]=0;
if(l==r)
{
tree[rt]=a[l];
sum[rt]=vis[a[l]];
return ;
}
int mid=l+r>>1;
build(lson),build(rson),pushup(root);
}
void update(lrt,int L,int R,int v)
{
if(L<=l&&r<=R)
{
sum[rt]=(r-l+1)*vis[v];
tree[rt]=(r-l+1)*v;
lazy[rt]=v;
return ;
}
pushdown(root);
int mid=l+r>>1;
if(L<=mid) update(lson,L,R,v);
if(mid<R) update(rson,L,R,v);
pushup(root);
}
void update(lrt,int pos,int v)
{
if(l==r)
{
tree[rt]+=v;
sum[rt]=vis[tree[rt]];
return ;
}
pushdown(root);
int mid=l+r>>1;
if(pos<=mid) update(lson,pos,v);
if(mid<pos) update(rson,pos,v);
pushup(root);
}
int query(lrt,int L,int R)
{
if(L<=l&&r<=R) return sum[rt];
pushdown(root);
int mid=l+r>>1,ans=0;
if(L<=mid) ans+=query(lson,L,R);
if(mid<R) ans+=query(rson,L,R);
pushup(root);
return ans;
}
int main()
{
memset(vis,0,sizeof(vis));
vis[1]=1;///1不是素数
for(int i=2;i<maxn;i++)
{
///cout<<i<<endl;
if(vis[i]) continue;
for(int j=i*2;j<maxn;j+=i) vis[j]=1;///这里一个wa点,如果使用i*i可能会爆数据。。。
}
for(int i=1;i<maxn;i++) vis[i]^=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,n,1);
for(int i=0;i<m;i++)
{
scanf("%s",s);
if(s[0]=='A')
{
scanf("%d%d",&x,&y);
update(1,n,1,y,x);
}
else if(s[0]=='Q')
{
scanf("%d%d",&x,&y);
printf("%d\n",query(1,n,1,x,y));
}
else
{
scanf("%d%d%d",&z,&x,&y);
update(1,n,1,x,y,z);
}
}
}
return 0;
}