不知道为什么,我写的 FHQ 答案会出现随机正确的情况,不知道是哈希还是 FHQ 的问题。
#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N = 4e5 + 5, bas = 71;
int n, m, cnt, rt, l, r, a, b;
char op, c;
string s;
ull h[N] = {1};
struct FHQ_Treap{int l, r, siz, k, v, tag;ull w1, w2;}t[N << 1];
int New (int vv)
{
t[++ cnt].siz = 1;
t[cnt].v = t[cnt].w1 = t[cnt].w2 = vv;
t[cnt].k = rand ();
return cnt;
}
void push_up (int x)
{
t[x].w1 = t[t[x].l].w1 * h[t[t[x].r].siz + 1] + t[t[x].r].w1 + t[x].v * h[t[t[x].r].siz];
t[x].w2 = t[t[x].r].w2 * h[t[t[x].l].siz + 1] + t[t[x].l].w2 + t[x].v * h[t[t[x].l].siz];
t[x].siz = t[t[x].l].siz + t[t[x].r].siz + 1;
}
void Swap (int &a, int &b){a ^= b ^= a ^= b;}
void Swap (ull &a, ull &b){a ^= b ^= a ^= b;}
void push_down (int x)
{
if (t[x].tag)
{
t[t[x].l].tag ^= 1;
t[t[x].r].tag ^= 1;
t[x].tag = 0;
Swap (t[x].l, t[x].r);
Swap (t[x].w1, t[x].w2);
}
}
void split (int pos, int x, int &l, int &r)
{
if (! pos)return l = r = 0, void ();
int tt = t[t[pos].l].siz + 1;
push_down (pos);
if (tt <= x)
{
l = pos;
split (t[l].r, x - tt, t[l].r, r);
}
else
{
r = pos;
split (t[r].l, x, l, t[r].l);
}
push_up (pos);
}
int merge (int l, int r)
{
if (! l || ! r)return l | r;
push_down (l);
push_down (r);
int pos;
if (t[l].k <= t[r].k)t[pos = l].r = merge (t[l].r, r);
else t[pos = r].l = merge (l, t[r].l);
push_up (pos);
return pos;
}
ull query (int L, int R)
{
int l1, r1;
split (rt, R, l, r);
split (l, L - 1, l1, r1);
ull d = t[r1].w1;
rt = merge (merge (l1, r1), r);
return d;
}
signed main ()
{
ios::sync_with_stdio (0), cin.tie (0), cout.tie (0);
srand (time (0));
for (int i = 1; i < N; ++ i)h[i] = h[i - 1] * bas;
while (cin >> n)
{
cnt = rt = 0;
memset (t, 0, sizeof (t));
cin >> m >> s;
s = " " + s;
for (int i = 1; i <= n; ++ i)rt = merge (rt, New (s[i] - '0'));
while (m --)
{
cin >> op >> a;
if (op == '4')
{
cin >> b;
if (a > b)Swap (a, b);
int L = 0, R = n - b + 1;
while (L < R)
{
int mid = L + R + 1 >> 1;
if (query (a, a + mid - 1) == query (b, b + mid - 1))L = mid;
else R = mid - 1;
}
cout << L << '\n';
}
if (op == '1')
{
cin >> c;
split (rt, a, l, r);
rt = merge (merge (l, New (c - '0')), r);
++ n;
}
if (op == '2')
{
int l1, r1;
split (rt, a, l, r);
split (l, a - 1, l1, r1);
r1 = merge (t[r1].l, t[r1].r);
rt = merge (merge (l1, r1), r);
-- n;
}
if (op == '3')
{
cin >> b;
if (a > b)Swap (a, b);
int l1, r1;
split (rt, b, l, r);
split (l, a - 1, l1, r1);
t[r1].tag ^= 1;
rt = merge (merge (l1, r1), r);
}
}
}
return 0;
}