ZOJ 3765 Lights (伸展树splay)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3765

 

Lights

Time Limit: 8 Seconds      Memory Limit: 131072 KB

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:

  1. L R status - Query the GCD (Greatest Common Divisor) of the value of the given status lights in range [LR]. For example, if now we have 3 lights which are {on, off and on}, and their value are {3, 5, 9}, then the GCD of the number of the lights on in [1, 3] is 3, and the lights off is 5.
  2. i value status - Add a light just behind to ith light. The initial status and the value is given also.
  3. i - Remove the ith light.
  4. i - If ith light is on, turn it off, else turn it on.
  5. i x - Modify the value of ith light to x.

 

Please help this boring guy to do this boring thing so that he can have time to find a girlfriend!

Input

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".

Output

For each Query operation, output an integer, which is the answer to the query. If no lights are with such status, please output -1.

Sample Input

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

Sample Output

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 }

 

 

 

posted on 2014-03-02 21:44  kuangbin  阅读(1741)  评论(0编辑  收藏  举报

导航

JAVASCRIPT: