P10058 Reverse and Rotate
sb 了,看到这题的第一反应是文艺平衡树。
再反转前记录累计有多少为要左移,然后翻转。
无语了,这么简单的题写这么复杂。
code:
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
mt19937 rnd(time(0));
const int N = 1e6+5;
int n, m, k, x, y, z, rt, cnt, siz[N], val[N], dat[N], tag[N], son[N][2];
char c[N];
inline int newnode(int v) { return siz[++cnt] = 1, val[cnt] = v, dat[cnt] = rnd(), cnt; }
inline void pushup(int x) { siz[x] = siz[son[x][0]]+siz[son[x][1]]+1; }
inline void pushdown(int x) {
if (!tag[x]) return;
swap(son[x][0], son[x][1]);
tag[son[x][0]] ^= 1;
tag[son[x][1]] ^= 1;
tag[x] = 0;
}
inline void split(int now, int k, int &x, int &y) {
if (!now) return (void)(x = y = 0);
pushdown(now);
if (siz[son[now][0]]+1 <= k) x = now, split(son[x][1], k-siz[son[now][0]]-1, son[x][1], y);
else y = now, split(son[y][0], k, x, son[y][0]);
pushup(now);
}
inline int merge(int x, int y) {
if (!x || !y) return x+y;
if (dat[x] > dat[y]) return pushdown(x), son[x][1] = merge(son[x][1], y), pushup(x), x;
return pushdown(y), son[y][0] = merge(x, son[y][0]), pushup(y), y;
}
inline void print(int now) {
pushdown(now);
if (son[now][0]) print(son[now][0]);
putchar(val[now]);
if (son[now][1]) print(son[now][1]);
}
int main() {
scanf("%s", c+1), m = read(); n = strlen(c+1);
for (int i = 1; i <= n; ++i) rt = merge(rt, newnode(c[i]));
while (m--) {
scanf("%s", c);
if (c[0] == '<') k = (k+read()%n)%n;
else if (c[0] == '>') k = (k-read()%n+n)%n;
else {
split(rt, k, x, y);
rt = merge(y, x);
tag[rt] ^= 1;
k = 0;
}
}
if (k) split(rt, k, x, y), rt = merge(y, x);
print(rt);
return 0;
}