ZOJ 3911Prime 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
#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); } } } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步