ZOJ3765---Lights (Splay伸展树)

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大法,熟练了之后 这种题就算是裸题了。。。 基本上都会用到 旋转 rotate, 伸展splay,获取第k的元素的位置 Get_kth,翻转reverse,删除delete函数。

这题因为数组开小TLE一上午,昨天晚上明明就已经是正确解法了,害我一直调试。

  1 #include <cstdio>

  2 #include <cstdlib>

  3 #include <cstring>

  4 #include <algorithm>

  5 using namespace std;

  6 const int maxn = 3e5+100;

  7 int siz[maxn],pre[maxn],ch[maxn][2],st[maxn],s[maxn];

  8 int key[maxn],GCD[2][maxn];

  9 int tot1,tot2,root,n,q;

 10 int gcd(int x,int y)

 11 {

 12     return y == 0 ? x : gcd (y,x % y);

 13 }

 14 void NewNode(int &r,int father,int k,int status)

 15 {

 16     if (tot2)

 17         r = s[tot2--];

 18     else

 19         r = ++tot1;

 20     pre[r] = father;

 21     ch[r][0] = ch[r][1] = 0;

 22     st[r] = status;

 23     key[r] = k;

 24     siz[r] = 1;

 25     GCD[0][r]  = GCD[1][r] = 0;

 26     GCD[st[r]][r] = k;

 27 }

 28 void push_up(int r)

 29 {

 30     siz[r] = siz[ch[r][0]] + siz[ch[r][1]] + 1;

 31     if (GCD[st[r]][r] == 0)

 32     {

 33         GCD[st[r]][r] = key[r];

 34     }

 35     GCD[0][r] = gcd(GCD[0][ch[r][0]],GCD[0][ch[r][1]]);

 36     GCD[1][r] = gcd(GCD[1][ch[r][0]],GCD[1][ch[r][1]]);

 37     GCD[st[r]][r] = gcd(GCD[st[r]][r],key[r]);   

 38 }

 39 int A[maxn];

 40 int B[maxn];                   // A  B 数组分别储存每个light的值以及状态

 41 void build(int &x,int l,int r,int father)

 42 {

 43     if (l > r)

 44         return;

 45     int mid = (l + r) >> 1;

 46     NewNode(x,father,A[mid],B[mid]);

 47     build(ch[x][0],l,mid-1,x);

 48     build(ch[x][1],mid+1,r,x);

 49     push_up(x);

 50 }

 51 void init()

 52 {

 53     root = tot1 = tot2 = 0;

 54     for (int i = 1; i <= n; i++)

 55         scanf ("%d%d",A+i,B+i);

 56     NewNode(root,0,1,0);

 57     NewNode(ch[root][1],root,1,0);

 58     build(ch[ch[root][1]][0],1,n,ch[root][1]);

 59     push_up(ch[root][1]);

 60     push_up(root);

 61 }

 62 void Rotate(int x,int kind)

 63 {

 64     int y = pre[x];

 65     ch[y][!kind] = ch[x][kind];

 66     pre[ch[x][kind]] = y;

 67     if (pre[y])

 68         ch[pre[y]][ch[pre[y]][1] == y] = x;

 69     pre[x] = pre[y];

 70     ch[x][kind] = y;

 71     pre[y] = x;

 72     push_up(y);

 73 }

 74 void Splay(int r,int goal)

 75 {

 76     while (pre[r] != goal)

 77     {

 78         if (pre[pre[r]] == goal)

 79         {

 80             Rotate(r,ch[pre[r]][0] == r);

 81         }

 82         else

 83         {

 84             int y = pre[r];

 85             int kind = (ch[pre[y]][1] == y);

 86             if (ch[y][kind] == r)

 87             {

 88                 Rotate(y,!kind);

 89                 Rotate(r,!kind);

 90             }

 91             else

 92             {

 93                 Rotate(r,kind);

 94                 Rotate(r,!kind);

 95             }

 96         }

 97     }

 98     push_up(r);

 99     if (goal == 0)

100         root = r;

101 }

102 int Get_kth(int r,int k)

103 {

104     int t = siz[ch[r][0]] + 1;

105     if (k == t)

106         return r;

107     if (k > t)

108         return Get_kth(ch[r][1],k-t);

109     else

110         return Get_kth(ch[r][0],k);

111 }

112 void Insert(int pos,int val,int status)

113 {

114     Splay(Get_kth(root,pos+1),0);

115     Splay(Get_kth(root,pos+2),root);

116     NewNode(ch[ch[root][1]][0],ch[root][1],val,status);

117     push_up(ch[root][1]);

118     push_up(root);

119 }

120 void eraser(int r)

121 {

122     if (!r)

123         return;

124     s[++tot2] = r;

125     eraser(ch[r][0]);

126     eraser(ch[r][1]);

127 }

128 void Delete(int pos)

129 {

130     Splay(Get_kth(root,pos),0);

131     Splay(Get_kth(root,pos+2),root);

132     eraser(ch[ch[root][1]][0]);

133     pre[ch[ch[root][1]][0]] = 0;

134     ch[ch[root][1]][0] = 0;

135     push_up(ch[root][1]);

136     push_up(root);

137 }

138 void modify (int pos,int val)

139 {

140     Splay(Get_kth(root,pos),0);

141     Splay(Get_kth(root,pos+2),root);

142     int key_value = ch[ch[root][1]][0];

143     key[key_value] = val;

144     push_up(ch[ch[root][1]][0]);

145     push_up(ch[root][1]);

146     push_up(root);

147 }

148 void reset(int pos)

149 {

150     Splay(Get_kth(root,pos),0);

151     Splay(Get_kth(root,pos+2),root);

152     int key_value = ch[ch[root][1]][0];

153     st[key_value] ^= 1;

154     push_up(ch[ch[root][1]][0]);

155     push_up(ch[root][1]);

156     push_up(root);

157 }

158 int query(int x,int y,int status)

159 {

160     Splay(Get_kth(root,x),0);

161     Splay(Get_kth(root,y+2),root);

162     push_up(ch[ch[root][1]][0]);

163     return GCD[status][ch[ch[root][1]][0]];

164 }

165 int main(void)

166 {

167     #ifndef ONLINE_JUDGE

168         freopen("in.txt","r",stdin);

169     #endif

170 

171     while (~scanf ("%d%d",&n,&q))

172     {

173         init();

174         for (int i = 0; i < q; i++)

175         {

176             char op[8];

177             scanf ("%s",op);

178             if (op[0] == 'Q')

179             {

180                 int x,y,z;

181                 scanf ("%d%d%d",&x,&y,&z);

182                 int ans = query(x,y,z);

183                 printf("%d\n",ans > 0 ? ans : -1);

184             }

185             if (op[0] == 'I')

186             {

187                 int x,z,y;

188                 scanf ("%d%d%d",&x,&y,&z);

189                 Insert(x,y,z);

190             }

191             if (op[0] == 'D')

192             {

193                 int x;

194                 scanf ("%d",&x);

195                 Delete(x);

196             }

197             if (op[0] == 'M')

198             {

199                 int x, z;

200                 scanf ("%d%d",&x,&z);

201                 modify(x,z);

202             }

203             if (op[0] == 'R')

204             {

205                 int x;

206                 scanf ("%d",&x);

207                 reset(x);

208             }

209         }

210     }

211     return 0;

212 }

 

你可能感兴趣的:(play)