关于我的 FHQ
  • 板块学术版
  • 楼主MnZnOIer
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/1/13 15:17
  • 上次更新2025/1/13 18:22:57
查看原帖
关于我的 FHQ
677091
MnZnOIer楼主2025/1/13 15:17

不知道为什么,我写的 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;
}
2025/1/13 15:17
加载中...