ZOJ 3911 Prime Query ZOJ Monthly, October 2015 - I

Prime Query

Time Limit: 1 Second      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

 

题意:维护一个长度为n的序列,有三种操作

A v u 给第u个点增加v的权值

R a l r 把第l到r的元素的权值全部改成a

Q l r 询问第l到r的元素中一共有多少素数

分析:显然的线段树裸题

先线性筛素数,然后维护一下就行

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <ctime>
  6 #include <iostream>
  7 #include <algorithm>
  8 #include <map>
  9 #include <set>
 10 #include <vector>
 11 #include <deque>
 12 #include <queue>
 13 using namespace std;
 14 typedef long long LL;
 15 typedef double DB;
 16 #define Rep(i, n) for(int i = (0); i < (n); i++)
 17 #define Repn(i, n) for(int i = (n)-1; i >= 0; i--)
 18 #define For(i, s, t) for(int i = (s); i <= (t); i++)
 19 #define Ford(i, t, s) for(int i = (t); i >= (s); i--)
 20 #define rep(i, s, t) for(int i = (s); i < (t); i++)
 21 #define repn(i, s, t) for(int i = (s)-1; i >= (t); i--)
 22 #define MIT (2147483647)
 23 #define MLL (1000000000000000000LL)
 24 #define INF (1000000001)
 25 #define mk make_pair
 26 #define ft first
 27 #define sd second
 28 #define clr(x, y) (memset(x, y, sizeof(x)))
 29 #define sqr(x) ((x)*(x))
 30 #define sz(x) ((int) (x).size())
 31 #define puf push_front
 32 #define pub push_back
 33 #define pof pop_front
 34 #define pob pop_back
 35 inline void SetIO(string Name) {
 36     string Input = Name+".in", Output = Name+".out";
 37     freopen(Input.c_str(), "r", stdin);
 38     freopen(Output.c_str(), "w", stdout);
 39 }
 40 
 41 const int N = 100010, M = 18, Max = 10000010;
 42 struct SegTree {
 43     int Tot, Tag, Child[2];
 44     #define Tot(x) (Tr[x].Tot)
 45     #define Tag(x) (Tr[x].Tag)
 46     #define Lc(x) (Tr[x].Child[0])
 47     #define Rc(x) (Tr[x].Child[1])
 48     #define Child(x, y) (Tr[x].Child[y])
 49 } Tr[N*M];
 50 int CTr;
 51 int Prime[Max], CPrime;
 52 bool NotPrime[Max];
 53 int n, m, Arr[N];
 54 
 55 inline void GetPrime() {
 56     CPrime = 0;
 57     For(i, 2, Max-1) {
 58         if(!NotPrime[i]) Prime[++CPrime] = i;
 59         For(j, 1, CPrime) {
 60             if(1LL*i*Prime[j] >= Max) break;
 61             NotPrime[i*Prime[j]] = 1;
 62             if(!(i%Prime[j])) break;
 63         }
 64     }
 65 }
 66 
 67 inline int Getint() {
 68     int Ret = 0;
 69     char Ch = ' ';
 70     while(!(Ch >= '0' && Ch <= '9')) Ch = getchar();
 71     while(Ch >= '0' && Ch <= '9') {
 72         Ret = Ret*10+Ch-'0';
 73         Ch = getchar();
 74     }
 75     return Ret;
 76 }
 77 
 78 inline void Solve();
 79 
 80 inline void Input() {
 81     GetPrime();
 82     int TestNumber;
 83     //scanf("%d", &TestNumber);
 84     TestNumber = Getint();
 85     while(TestNumber--) {
 86         //scanf("%d%d", &n, &m);
 87         n = Getint();
 88         m = Getint();
 89         For(i, 1, n) scanf("%d", Arr+i);
 90         Solve();
 91     }
 92 }
 93 
 94 inline void Init() {
 95     CTr = 0;
 96 }
 97 
 98 inline void Updata(int x) {
 99     Tot(x) = 0;
100     Rep(i, 2)
101         Tot(x) += Tot(Child(x, i));
102 }
103 
104 inline void Draw(int x, int Left, int Right, int a) {
105     if(Left == Right) {
106         Arr[Left] = a;
107         Tot(x) = !NotPrime[a];
108     } else {
109         Tag(x) = a;
110         if(NotPrime[a]) Tot(x) = 0;
111         else Tot(x) = Right-Left+1;
112     }
113 }
114 
115 inline void PushDown(int x, int L, int R) {
116     if(!Tag(x)) return;
117     int Mid = (L+R)>>1;
118     Draw(Lc(x), L, Mid, Tag(x));
119     Draw(Rc(x), Mid+1, R, Tag(x));
120     Tag(x) = 0;
121 }
122 
123 inline void Build(int Left, int Right) {
124     int Mid = (Left+Right)>>1;
125     int x = ++CTr;
126     clr(Tr[x].Child, 0), Tot(x) = Tag(x) = 0;
127     if(Left == Right) Tot(x) = !NotPrime[Arr[Left]];
128     else {
129         Lc(x) = CTr+1;
130         Build(Left, Mid);
131         Rc(x) = CTr+1;
132         Build(Mid+1, Right);
133         Updata(x);
134     }
135 }
136 
137 inline void Add(int x, int Left, int Right, int v, int a) {
138     int Mid = (Left+Right)>>1;
139     if(Left == Right) {
140         Arr[v] += a;
141         Tot(x) = !NotPrime[Arr[v]];
142     } else {
143         if(Tag(x)) PushDown(x, Left, Right);
144         
145         if(v <= Mid) Add(Lc(x), Left, Mid, v, a);
146         else Add(Rc(x), Mid+1, Right, v, a);
147         Updata(x);
148     }
149 }
150 
151 inline int Query(int x, int Left, int Right, int L, int R) {
152     if(Left >= L && Right <= R) return Tot(x);
153     else {
154         int Mid = (Left+Right)>>1, Ret = 0;
155         
156         if(Tag(x)) PushDown(x, Left, Right);
157         
158         if(R <= Mid) Ret = Query(Lc(x), Left, Mid, L, R);
159         else if(L > Mid) Ret = Query(Rc(x), Mid+1, Right, L, R);
160         else {
161             Ret = Query(Lc(x), Left, Mid, L, Mid);
162             Ret += Query(Rc(x), Mid+1, Right, Mid+1, R);
163         }
164         return Ret;
165     }
166 }
167 
168 inline void Change(int x, int Left, int Right, int L, int R, int a) {
169     if(Left >= L && Right <= R) Draw(x, Left, Right, a);
170     else {
171         int Mid = (Left+Right)>>1;
172         
173         if(Tag(x)) PushDown(x, Left, Right);
174         
175         if(R <= Mid) Change(Lc(x), Left, Mid, L, R, a);
176         else if(L > Mid) Change(Rc(x), Mid+1, Right, L, R, a);
177         else {
178             Change(Lc(x), Left, Mid, L, Mid, a);
179             Change(Rc(x), Mid+1, Right, Mid+1, R, a);
180         }
181         Updata(x);
182     }
183 }
184 
185 inline void Solve() {
186     Init();
187     Build(1, n);
188     
189     char Opt;
190     int L, R, v, a, Ans;
191     while(m--) {
192         for(Opt = ' '; Opt != 'A' && Opt != 'Q' && Opt != 'R'; Opt = getchar());
193         
194         if(Opt == 'A') {
195             a = Getint();
196             v = Getint();
197             Add(1, 1, n, v, a);
198         } else if(Opt == 'Q') {
199             L = Getint();
200             R = Getint();
201             Ans = Query(1, 1, n, L, R);
202             printf("%d\n", Ans);
203         } else {
204             a = Getint();
205             L = Getint();
206             R = Getint();
207             Change(1, 1, n, L, R, a);
208         }
209     }
210 }
211 
212 int main() {
213      Input();
214      //Solve();
215     return 0;
216 }
View Code

 

posted @ 2015-10-16 19:46  yanzx6  阅读(219)  评论(0编辑  收藏  举报