POJ3580---SuperMemo (Splay)

各种操作,区间更新,求最值、翻转、插入、删除、当然是Splay这种神器了。

主要是 revolve这个操作,其实也就是3个区间翻转放到一块,

比如 REVOLVE x y T,T %= (y-x+1); 其实就是 先把 x y区间翻转,然后把  x x + c - 1区间和 x+ c  y区间分别翻转。

代码:

  1 #include <set>

  2 #include <map>

  3 #include <cmath>

  4 #include <ctime>

  5 #include <queue>

  6 #include <stack>

  7 #include <cstdio>

  8 #include <string>

  9 #include <vector>

 10 #include <cstdlib>

 11 #include <cstring>

 12 #include <iostream>

 13 #include <algorithm>

 14 using namespace std;

 15 typedef unsigned long long ull;

 16 typedef long long ll;

 17 const int inf = 0x3f3f3f3f;

 18 const double eps = 1e-8;

 19 const int maxn = 1e5+100;

 20 int siz[maxn],minv[maxn],rev[maxn],addv[maxn],key[maxn];

 21 int ch[maxn][2],a[maxn],pre[maxn],s[maxn];

 22 int n,tot1,tot2,root;

 23 void NewNode(int &r,int father,int k)

 24 {

 25     if (tot2)

 26         r = s[tot2--];

 27     else

 28         r = ++tot1;

 29     pre[r] = father;

 30     key[r] = k;

 31     siz[r] = 1;

 32     minv[r] = k;

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

 34 }

 35 void update_Rev(int r)

 36 {

 37     if (!r)

 38         return ;

 39     swap(ch[r][0],ch[r][1]);

 40     rev[r] ^= 1;

 41 }

 42 void push_up(int r)

 43 {

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

 45     minv[r] = min(key[r],min(minv[ch[r][0]],minv[ch[r][1]]));

 46 }

 47 void update_add(int r,int val)

 48 {

 49     if (!r)

 50         return ;

 51     key[r] += val;

 52     addv[r] += val;

 53     minv[r] += val;

 54 }

 55 void push_down(int r)

 56 {

 57     if (rev[r])

 58     {

 59         update_Rev(ch[r][0]);

 60         update_Rev(ch[r][1]);

 61         rev[r] = 0;

 62     }

 63     if (addv[r])

 64     {

 65         update_add(ch[r][0],addv[r]);

 66         update_add(ch[r][1],addv[r]);

 67         addv[r] = 0;

 68     }

 69 }

 70 

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

 72 {

 73     if (l > r)

 74         return;

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

 76     NewNode(x,father,a[mid]);

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

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

 79     push_up(x);

 80 }

 81 void init()

 82 {

 83     tot1 = root = tot2 = 0;

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

 85         scanf ("%d",a+i);

 86     minv[root] = inf;

 87     NewNode(root,0,-1);

 88     NewNode(ch[root][1],root,-1);

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

 90     push_up(root);

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

 92 }

 93 void Rotate(int x,int kind)

 94 {

 95     int y = pre[x];

 96     push_down(y);

 97     push_down(x);

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

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

100     if (pre[y])

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

102     pre[x] = pre[y];

103     ch[x][kind] = y;

104     pre[y] = x;

105     push_up(y);

106 }

107 void Splay(int r,int goal)

108 {

109     push_down(r);

110     while (pre[r] != goal)

111     {

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

113         {

114             push_down(pre[r]);

115             push_down(r);

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

117         }

118         else

119         {

120             int y = pre[r];

121             push_down(pre[y]);

122             push_down(y);

123             push_down(r);

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

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

126             {

127                 Rotate(y,!kind);

128                 Rotate(r,!kind);

129             }

130             else

131             {

132                 Rotate(r,kind);

133                 Rotate(r,!kind);

134             }

135         }

136     }

137     push_up(r);

138     if (goal == 0)

139         root = r;

140 }

141 int Get_kth(int r,int k)

142 {

143     push_down(r);

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

145     if (t == k)

146         return r;

147     else if (t <= k)

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

149     else

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

151 }

152 void eraser(int r)

153 {

154     if (!r)

155         return;

156     s[++tot2] = r;

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

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

159 }

160 void Delete(int x)

161 {

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

163     Splay(Get_kth(root,x+2),root);

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

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

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

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

168     push_up(root);

169 }

170 void Insert(int x,int val)

171 {

172     Splay(Get_kth(root,x+1),0);

173     Splay(Get_kth(root,x+2),root);

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

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

176     push_up(root);

177 }

178 void ADD(int u,int v,int val)

179 {

180     Splay(Get_kth(root,u),0);

181     Splay(Get_kth(root,v+2),root);

182     update_add(ch[ch[root][1]][0],val);

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

184     push_up(root);

185 }

186 int query(int ua,int ub)

187 {

188     Splay(Get_kth(root,ua),0);

189     Splay(Get_kth(root,ub+2),root);

190     return minv[ch[ch[root][1]][0]];

191 }

192 void Reverse (int u,int v)

193 {

194     Splay (Get_kth(root,u),0);

195     Splay (Get_kth(root,v+2),root);

196     update_Rev (ch[ch[root][1]][0]);

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

198     push_up (root);

199 }

200 void revolve(int u,int v,int c)

201 {

202     int len = (v - u + 1);

203     c  %= len;

204     if (!c)

205         return;

206     Reverse(u,v);

207     Reverse(u,u+c-1);

208     Reverse(u+c,v);

209 }

210 int main(void)

211 {

212     #ifndef ONLINE_JUDGE

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

214     #endif

215     while (~scanf ("%d",&n))

216     {

217         init();

218         int m;

219         scanf ("%d",&m);

220         for (int i = 0; i < m; i++)

221         {

222             char op[10];

223             int u,v,c;

224             scanf ("%s",op);

225             if (strcmp(op,"ADD") == 0)

226             {

227                 scanf ("%d%d%d",&u,&v,&c);

228                 ADD(u,v,c);

229             }

230             if (strcmp(op,"REVERSE") == 0)

231             {

232                 scanf ("%d%d",&u,&v);

233                 Reverse(u,v);

234             }

235             if (strcmp(op,"REVOLVE") == 0)

236             {

237                 scanf ("%d%d%d",&u,&v,&c);

238                 revolve(u,v,c);

239             }

240             if (strcmp(op,"INSERT") == 0)

241             {

242                 scanf ("%d%d",&u,&v);

243                 Insert(u,v);

244             }

245             if (strcmp(op,"DELETE") == 0)

246             {

247                 scanf ("%d",&u);

248                 Delete(u);

249             }

250             if (strcmp(op,"MIN") == 0)

251             {

252                 scanf ("%d%d",&u,&v);

253                 printf("%d\n",query(u,v));

254             }

255         }

256     }

257     return 0;

258 }

 

你可能感兴趣的:(super)