题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3765
Now you have N lights in a line. Don't worry - the lights don't have color. The only status they have is on and off. And, each light has a value, too.
There is a boring student in ZJU. He decides to do some boring operations to the lights:
Please help this boring guy to do this boring thing so that he can have time to find a girlfriend!
The input contains multiple test cases. Notice there's no empty line between each test case.
For each test case, the first line of the a case contains two integers, N (1 ≤ N ≤ 200000) and Q (1 ≤ Q ≤ 100000), indicating the number of the lights at first and the number of the operations. In following N lines, each line contains two integers, Numi (1 ≤ Numi ≤ 1000000000) and Statusi (0 ≤ Statusi ≤ 1), indicating the number of the light i and the status of it. In following Q lines, each line indicating an operation, and the format is described above.
It is guaranteed that the range of the operations will be appropriate. For example, if there is only 10 lights, you will not receive an operation like "Q 1 11 0" or "D 11".
For each Query operation, output an integer, which is the answer to the query. If no lights are with such status, please output -1.
3 12 27 1 32 0 9 1 Q 1 3 1 I 3 64 0 Q 2 4 0 Q 2 4 1 I 2 43 1 D 5 Q 1 2 1 M 1 35 Q 1 2 1 R 1 R 3 Q 1 2 1
9 32 9 27 35 -1
很裸的题目了,用splay维护也很简单,练练手而已。
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2014/3/2 20:02:38 4 File Name :E:\2014ACM\比赛\ZOJ_March2014\I.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 #define Key_value ch[ch[root][1]][0] 21 const int MAXN = 300010; 22 int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN]; 23 int root,tot1; 24 int sum0[MAXN],sum1[MAXN];//该子树对应状态的gcd 25 int st[MAXN]; //该节点的状态 26 int s[MAXN],tot2;//内存池和容量 27 //初始节点的值和状态 28 int a[MAXN]; 29 int status[MAXN]; 30 int n,q; 31 32 long long gcd(long long a,long long b) 33 { 34 if(b == 0)return a; 35 else return gcd(b,a%b); 36 } 37 void NewNode(int &r,int father,int k,int _st) 38 { 39 if(tot2) r = s[tot2--]; 40 else r = ++tot1; 41 pre[r] = father; 42 ch[r][0] = ch[r][1] = 0; 43 key[r] = k; 44 st[r] = _st; 45 if(_st == 0){sum0[r] = k; sum1[r] = 0;} 46 else {sum1[r] = k; sum0[r] = 0;} 47 size[r] = 1; 48 } 49 void push_up(int r) 50 { 51 int lson = ch[r][0], rson = ch[r][1]; 52 size[r] = size[lson] + size[rson] + 1; 53 sum0[r] = sum1[r] = 0; 54 sum0[r] = gcd(sum0[lson],sum0[rson]); 55 sum1[r] = gcd(sum1[lson],sum1[rson]); 56 if(st[r])sum1[r] = gcd(sum1[r],key[r]); 57 else sum0[r] = gcd(sum0[r],key[r]); 58 } 59 void push_down(int r) 60 { 61 62 } 63 void Build(int &x,int l,int r,int father) 64 { 65 if(l > r)return; 66 int mid = (l + r)/2; 67 NewNode(x,father,a[mid],status[mid]); 68 Build(ch[x][0],l,mid-1,x); 69 Build(ch[x][1],mid+1,r,x); 70 push_up(x); 71 } 72 void Init() 73 { 74 root = tot1 = tot2 = 0; 75 ch[root][0] = ch[root][1] = size[root] = pre[root] = 0; 76 sum0[root] = sum1[root] = 0; 77 NewNode(root,0,0,0); 78 NewNode(ch[root][1],root,0,0); 79 for(int i = 0;i < n;i++) 80 scanf("%d%d",&a[i],&status[i]); 81 Build(Key_value,0,n-1,ch[root][1]); 82 push_up(ch[root][1]); 83 push_up(root); 84 } 85 void Rotate(int x,int kind) 86 { 87 int y = pre[x]; 88 push_down(y); 89 push_down(x); 90 ch[y][!kind] = ch[x][kind]; 91 pre[ch[x][kind]] = y; 92 if(pre[y]) 93 ch[pre[y]][ch[pre[y]][1]==y] = x; 94 pre[x] = pre[y]; 95 ch[x][kind] = y; 96 pre[y] = x; 97 push_up(y); 98 } 99 void Splay(int r,int goal) 100 { 101 push_down(r); 102 while(pre[r] != goal) 103 { 104 if(pre[pre[r]] == goal) 105 { 106 Rotate(r,ch[pre[r]][0] == r); 107 } 108 else 109 { 110 int y = pre[r]; 111 int kind = ch[pre[y]][0] == y; 112 if(ch[y][kind] == r) 113 { 114 Rotate(r,!kind); 115 Rotate(r,kind); 116 } 117 else 118 { 119 Rotate(y,kind); 120 Rotate(r,kind); 121 } 122 } 123 } 124 push_up(r); 125 if(goal == 0)root = r; 126 } 127 int Get_kth(int r,int k) 128 { 129 push_down(r); 130 int t = size[ch[r][0]] + 1; 131 if(t == k)return r; 132 if(t > k)return Get_kth(ch[r][0],k); 133 else return Get_kth(ch[r][1],k-t); 134 } 135 //在第pos个数后面插入一个数 136 void Insert(int pos,int _val,int _st) 137 { 138 Splay(Get_kth(root,pos+1),0); 139 Splay(Get_kth(root,pos+2),root); 140 NewNode(Key_value,ch[root][1],_val,_st); 141 push_up(ch[root][1]); 142 push_up(root); 143 } 144 void erase(int r) 145 { 146 if(!r)return; 147 s[++tot2] = r; 148 erase(ch[r][0]); 149 erase(ch[r][1]); 150 } 151 //删除第pos个数 152 void Delete(int pos) 153 { 154 Splay(Get_kth(root,pos),0); 155 Splay(Get_kth(root,pos+2),root); 156 erase(Key_value); 157 pre[Key_value] = 0; 158 Key_value = 0; 159 push_up(ch[root][1]); 160 push_up(root); 161 } 162 //改变第pos个数的状态 163 void Change(int pos) 164 { 165 Splay(Get_kth(root,pos),0); 166 Splay(Get_kth(root,pos+2),root); 167 st[Key_value] ^= 1; 168 push_up(Key_value); 169 push_up(ch[root][1]); 170 push_up(root); 171 } 172 //改变第pos个数的值 173 void Modify(int pos,int _val) 174 { 175 Splay(Get_kth(root,pos),0); 176 Splay(Get_kth(root,pos+2),root); 177 key[Key_value] = _val; 178 push_up(Key_value); 179 push_up(ch[root][1]); 180 push_up(root); 181 182 } 183 int Query(int L,int R,int _st) 184 { 185 int ans ; 186 Splay(Get_kth(root,L),0); 187 Splay(Get_kth(root,R+2),root); 188 if(_st == 0)ans = sum0[Key_value]; 189 else ans = sum1[Key_value]; 190 if(ans == 0)ans = -1; 191 return ans; 192 } 193 194 int main() 195 { 196 //freopen("in.txt","r",stdin); 197 //freopen("out.txt","w",stdout); 198 while(scanf("%d%d",&n,&q) == 2) 199 { 200 Init(); 201 char op[10]; 202 while(q--) 203 { 204 scanf("%s",op); 205 if(op[0] == 'Q') 206 { 207 int L,R,_st; 208 scanf("%d%d%d",&L,&R,&_st); 209 printf("%d\n",Query(L,R,_st)); 210 } 211 else if(op[0] == 'I') 212 { 213 int pos,val,_st; 214 scanf("%d%d%d",&pos,&val,&_st); 215 Insert(pos,val,_st); 216 } 217 else if(op[0] == 'D') 218 { 219 int pos; 220 scanf("%d",&pos); 221 Delete(pos); 222 } 223 else if(op[0] == 'R') 224 { 225 int pos; 226 scanf("%d",&pos); 227 Change(pos); 228 } 229 else if(op[0] == 'M') 230 { 231 int pos,val; 232 scanf("%d%d",&pos,&val); 233 Modify(pos,val); 234 } 235 } 236 } 237 return 0; 238 }