ZOJ 3911Prime Query [素数处理 + 线段树]

来源:互联网 发布:跨河水准测量数据整理 编辑:程序博客网 时间:2024/06/05 00:20

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

#include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <string>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#define INF 0x3f3f3f3f#define EPS 0.00000001#define lowbit(x) (x&(-x))using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 1e5+7;const int N = 1e7+7;int t[maxn << 2],in[maxn << 2],lazy[maxn << 2];int prime[N];void getprime(){    for(int i=2;i<sqrt(1.0*N);i++)        if(!prime[i])            for(int j=i+i;j<N;j+=i)                prime[j] = 1;    prime[1] = 1;    prime[0] = 1;}void pushdown(int i,int b,int e){    if(lazy[i])    {        int mid = (b + e) / 2;        in[i << 1] = !prime[lazy[i]] * (mid - b + 1);        in[i << 1 | 1] = !prime[lazy[i]] * (e - mid);        t[i << 1] = lazy[i];        t[i << 1 | 1] = lazy[i];        lazy[i << 1] = lazy[i];        lazy[i << 1 | 1] = lazy[i];        lazy[i] = 0;    }}void add(int i,int b,int e,int pos,int val){    if(b == e)    {        in[i] -= !prime[t[i]];        t[i] += val;        in[i] += !prime[t[i]];        return ;    }    pushdown(i, b, e);    int mid = (b + e) / 2;    if(pos <= mid) add(i << 1, b, mid, pos, val);    else add(i << 1 | 1, mid + 1, e, pos, val);    in[i] = in[i << 1] + in[i << 1 | 1];}void replace(int i,int b,int e,int l,int r,int val){    if(b >= l && e <= r)    {        in[i] = (!prime[val]) * (e - b + 1);        t[i] = val;        lazy[i] = val;        return ;    }    pushdown(i, b, e);    int mid = (b + e) / 2;    if(r <= mid) replace(i << 1, b, mid, l, r, val);    else if(l > mid) replace(i<< 1 | 1, mid + 1, e, l, r, val);    else    {        replace(i << 1, b, mid, l, r, val);        replace(i << 1 | 1, mid + 1, e, l, r, val);    }    in[i] = in[i << 1] + in[i << 1 | 1];}int query(int i,int b,int e,int l,int r){    if(b >= l && e <= r)        return in[i];    pushdown(i, b, e);    int mid = (b + e) / 2;    if(r <= mid) return query(i << 1, b, mid, l, r);    else if(l > mid) return query(i << 1 | 1, mid + 1, e, l, r);    else return query(i << 1, b, mid, l, r) + query(i << 1 | 1, mid + 1, e, l, r);}int main(){    getprime();    int T;    scanf("%d",&T);    while(T--)    {        char s[5];        int n,m,x,a,b,c;        scanf("%d%d",&n,&m);        memset(t,0,sizeof(t));        memset(in,0,sizeof(in));        memset(lazy,0,sizeof(lazy));        for(int i=1;i<=n;i++)        {            scanf("%d",&x);            add(1,1,n,i,x);        }        for(int i=0;i<m;i++)        {            scanf("%s%d%d",s,&a,&b);            if(s[0] == 'A') add(1,1,n,b,a);            else if(s[0] == 'Q') printf("%d\n", query(1,1,n,a,b));            else            {                scanf("%d",&c);                replace(1,1,n,b,c,a);            }        }    }}
原创粉丝点击