ZOJ 3911 Prime Query ZOJ Monthly, October 2015 - I
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 }