QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#864727#5037. 回文Felix720 0ms0kbC++1411.3kb2025-01-20 22:20:412025-01-20 22:20:42

Judging History

This is the latest submission verdict.

  • [2025-01-20 22:20:42]
  • Judged
  • Verdict: 0
  • Time: 0ms
  • Memory: 0kb
  • [2025-01-20 22:20:41]
  • Submitted

answer

/* Good Game, Well Play. */
#include <bits/stdc++.h>
#define lowbit(x) ((x) & (-(x)))
using namespace std;

const int N = 200010, P = 131;
const long long mod = 10000000000000061;
int n, m, B; string s; long long pw[N];

bool Entag = false; int Enl, Enr;
struct Blocks
{
	int bid[N]; long long pre[N], suf[N];
	struct Part
	{
		int l, r; long long val[2];
		vector < long long > hsh[2];
		inline void rebuild()
		{
			for(int op = 0; op <= 1; ++op)
				val[op] = 0, hsh[op].resize(r - l + 3);
			for(int j = l; j <= r; ++j)
			{
				val[0] = ((__int128)val[0] * P + s[j]) % mod;
				hsh[0][j - l + 1] = val[0];
			}
			for(int j = r; j >= l; --j)
			{
				val[1] = ((__int128)val[1] * P + s[j]) % mod;
				hsh[1][j - l + 1] = val[1];
			}
		}
	}; Part part[N];
	inline void init_sum()
	{
		for(int i = 1; i <= bid[n]; ++i)
			pre[i] = ((__int128)pre[i - 1] * pw[part[i].r - part[i].l + 1] + part[i].val[0]) % mod;
		for(int i = bid[n]; i >= 1; --i)
			suf[i] = ((__int128)suf[i + 1] * pw[part[i].r - part[i].l + 1] + part[i].val[1]) % mod;
	}
	inline long long in_query(int op, int id, int l, int r)
	{
		if(op == 0) return (part[id].hsh[0][r] - (__int128)part[id].hsh[0][l - 1] * pw[r - l + 1] % mod + mod) % mod;
		else return (part[id].hsh[1][l] - (__int128)part[id].hsh[1][r + 1] * pw[r - l + 1] % mod + mod) % mod;
	}
	
	inline void _setup()
	{
		B = sqrt(n);
		for(int i = 1; i <= n; ++i) bid[i] = (i - 1) / B + 1;
		for(int i = 1; i <= bid[n]; ++i)
		{
			part[i].l = B * (i - 1) + 1;
			part[i].r = min(B * i, n);
			part[i].rebuild();
		}
		init_sum();
	}
	inline void _modify(int p)
	{
		part[bid[p]].rebuild();
		init_sum();
	}
	inline long long _query(int op, int l, int r)
	{
		if(Entag)
		{
			op ^= 1; swap(l, r);
			l = Enr - (l - Enl);
			r = Enr - (r - Enl);
		}
		if(l > r) return 0;
		if(bid[l] == bid[r]) return in_query(op, bid[l], l - part[bid[l]].l + 1, r - part[bid[l]].l + 1);
		else
		{
			long long res = 0;
			if(op == 0)
			{
				res = in_query(0, bid[l], l - part[bid[l]].l + 1, part[bid[l]].r - part[bid[l]].l + 1);
				if(bid[l] + 1 < bid[r])
				{
					res = (__int128)res * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod;
					res = (res + (pre[bid[r] - 1] - (__int128)pre[bid[l]] * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod + mod)) % mod;
				}
				res = (__int128)res * pw[r - part[bid[r]].l + 1] % mod;
				res = (res + in_query(0, bid[r], 1, r - part[bid[r]].l + 1)) % mod;
			}
			else
			{
				res = in_query(1, bid[r], 1, r - part[bid[r]].l + 1);
				if(bid[l] + 1 < bid[r])
				{
					res = (__int128)res * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod;
					res = (res + (suf[bid[l] + 1] - (__int128)suf[bid[r]] * pw[part[bid[r] - 1].r - part[bid[l]].r] % mod + mod)) % mod;
				}
				res = (__int128)res * pw[part[bid[l]].r - l + 1] % mod;
				res = (res + in_query(1, bid[l], l - part[bid[l]].l + 1, part[bid[l]].r - part[bid[l]].l + 1)) % mod;
			}
			return res;
		}
	}
}; Blocks blocks;

struct Seq
{
	int x, d, l;
	bool operator < (const Seq &w) const {return x < w.x;}
	bool operator > (const Seq &w) const {return x > w.x;}
};
inline vector < Seq > compress(vector < Seq > vec)
{
	sort(vec.begin(), vec.end());
//	cerr << "+++++++++++++++++++++++++++++++++++++++\n";
//	for(Seq sq : vec) cerr << "org " << sq.x << " " << sq.d << " " << sq.l << '\n';
	vector < Seq > res;
	for(Seq sq : vec)
	{
		if(!res.empty())
		{
			if(res.back().l == 1 && sq.l == 1)
				res.back().d = sq.x - res.back().x, ++res.back().l;
			else if(res.back().l == 1 && sq.x - res.back().x == sq.d)
				res.back().d = sq.d, res.back().l += sq.l;
			else if(sq.l == 1 && sq.x - (res.back().x + res.back().d * (res.back().l - 1)) == res.back().d)
				++res.back().l;
			else if(res.back().l > 1 && sq.l > 1 && res.back().d == sq.d && sq.x - (res.back().x + res.back().d * (res.back().l - 1)) == res.back().d)
				res.back().l += sq.l;
			else res.push_back(sq);
		}
		else res.push_back(sq);
	}
//	for(Seq sq : res) cerr << "final " << sq.x << " " << sq.d << " " << sq.l << '\n';
	return res;
}
struct Data
{
	int l, r;
	vector < Seq > pr, su;
	inline void unit(int p)
	{
		l = r = p;
		pr.clear(); su.clear();
		pr.push_back({1, 1, 1});
		su.push_back({1, 1, 1});
	}
	inline void reset(int ln, int rn)
	{l = ln, r = rn, pr.clear(), su.clear();}
	inline void debug()
	{
		cerr << "pr : ";
		for(Seq sq : pr) cerr << "(" << sq.x << "," << sq.d << "," << sq.l << ") ";
		cerr << '\n';
		cerr << "su : ";
		for(Seq sq : su) cerr << "(" << sq.x << "," << sq.d << "," << sq.l << ") ";
		cerr << '\n';
	}
};
const bool Enop[5] = {false, true, true, true, true};
inline void work(Data u, Data v, int l, int mid, int r, Data &res)
{
//	cerr << "work " << l << " " << mid << " " << r << '\n';
//	for(int i = l; i <= r; ++i) cerr << s[i]; cerr << '\n';
//	u.debug(); cerr << '\n'; v.debug();
	// Case I
	if(Enop[1])
	{
		res.su = v.su;
	}
	// Case II
	if(Enop[2])
	{
		for(Seq sq : v.pr)
		{
//			cerr << "! " << sq.x << " " << sq.d << " " << sq.l << '\n';
			if(sq.l == 1)
			{
				if(sq.x != r - mid && l <= mid - (r - mid - sq.x) + 1 && blocks._query(0, mid + sq.x + 1, r) == blocks._query(1, mid - (r - mid - sq.x) + 1, mid))
					res.su.push_back({sq.x + 2 * (r - mid - sq.x), 1, 1});
			}
			else
			{
				int ex = r - mid - (sq.x + sq.d * (sq.l - 1));
				if(!ex || blocks._query(0, mid + sq.x + sq.d * (sq.l - 1) + 1, r) == blocks._query(0, mid + sq.x + 1, mid + sq.x + (r - mid - sq.x - sq.d * (sq.l - 1))))
				{
					int head = (ex ? 0 : 1), tail = sq.l - 1, lim = -1;
					while(head <= tail)
					{
						int md = (head + tail) >> 1;
						if(l <= mid - (md * sq.d + ex) + 1 && blocks._query(0, r - (md * sq.d + ex) + 1, r) == blocks._query(1, mid - (md * sq.d + ex) + 1, mid))
							lim = md, head = md + 1;
						else tail = md - 1;
					}
					if(lim != -1)
					{
//						cerr << "lim " << lim << '\n';
						if(ex) res.su.push_back({(r - mid) + ex, sq.d, lim + 1});
						else res.su.push_back({(r - mid) + sq.d, sq.d, lim});
					}
				}
				else
				{
					int head = 1, tail = sq.l - 1, lim = 0;
					while(head <= tail)
					{
						int md = (head + tail) >> 1;
						if(l <= mid - md * sq.d + 1 && blocks._query(1, mid - md * sq.d + 1, mid) == blocks._query(0, mid + sq.x + 1, mid + sq.x + md * sq.d))
							lim = md, head = md + 1;
						else tail = md - 1;
					}
					if(l <= mid - lim * sq.d - ex + 1 && blocks._query(1, mid - lim * sq.d - ex + 1, mid) == blocks._query(0, r - (lim * sq.d + ex) + 1, r))
						res.su.push_back({r - mid + lim * sq.d + ex, 1, 1});
				}
			}
		}
	}
	// Case III
	if(Enop[3])
	{
		if(r - mid <= mid - l + 1)
		{
			if(blocks._query(0, mid + 1, r) == blocks._query(1, mid - (r - mid) + 1, mid))
				res.su.push_back({2 * (r - mid), 1, 1});
		}
	}
	// Case IV
	if(Enop[4])
	{
		for(Seq sq : u.su)
		{
			if(sq.l == 1)
			{
				if(l <= mid - sq.x - (r - mid) + 1 && blocks._query(0, mid + 1, r) == blocks._query(1, mid - sq.x - (r - mid) + 1, mid - sq.x))
					res.su.push_back({sq.x + 2 * (r - mid), 1, 1});
			}
			else
			{
				if(mid - sq.x - (r - mid) + 1 < l) continue;
				int head = 1, tail = (sq.l - 1) * sq.d, lim = 0;
				while(head <= tail)
				{
					int md = (head + tail) >> 1;
					if(mid + md <= r && blocks._query(0, mid + 1, mid + md) == blocks._query(1, mid - sq.x - md + 1, mid - sq.x))
						lim = md, head = md + 1;
					else tail = md - 1;
				}
				if(lim == r - mid)
				{
					head = 0, tail = sq.l - 1, lim = -1;
					while(head <= tail)
					{
						int md = (head + tail) >> 1;
						if(l <= mid - sq.x - md * sq.d - (r - mid) + 1 && blocks._query(0, mid - sq.x - md * sq.d - (r - mid) + 1, mid - sq.x - md * sq.d) == blocks._query(1, mid + 1, r))
							lim = md, head = md + 1;
						else tail = md - 1;
					}
					if(lim != -1) res.su.push_back({sq.x + 2 * (r - mid), sq.d, lim + 1});
				}
				else
				{
					head = 0, tail = sq.l - 1, lim = 0;
					while(head <= tail)
					{
						int md = (head + tail) >> 1;
						if(mid + md * sq.d <= r && blocks._query(0, mid - sq.x - sq.d * md + 1, mid - sq.x) == blocks._query(1, mid + 1, mid + sq.d * md))
							lim = md, head = md + 1;
						else tail = md - 1;
					}
					lim *= sq.d;
					if(l <= mid - sq.x - sq.d * (sq.l - 1) - (r - mid - lim) + 1)
					{
						if(blocks._query(0, mid - sq.x - sq.d * (sq.l - 1) - (r - mid - lim) + 1, r) == blocks._query(1, mid - sq.x - sq.d * (sq.l - 1) - (r - mid - lim) + 1, r))
							res.su.push_back({sq.x + (sq.d * (sq.l - 1) - lim) + (r - mid) * 2, 1, 1});
					}
				}
			}
		}
	}
}
Data operator + (Data u, Data v)
{
	int l = u.l, mid = u.r, r = v.r;
	Data res; res.reset(l, r);
	
	// -------------- Suffix --------------
	Entag = false; work(u, v, l, mid, r, res);
	// -------------- Prefix --------------
	Entag = true; Enl = l, Enr = r;
	for(int i = l; i <= r; ++i) if(i <= r - (i - l)) swap(s[i], s[r - (i - l)]);
	swap(u, v);
	swap(res.pr, res.su), swap(u.pr, u.su), swap(v.pr, v.su);
	work(u, v, l, r - (mid - l) - 1, r, res);
	for(int i = l; i <= r; ++i) if(i <= r - (i - l)) swap(s[i], s[r - (i - l)]);
	swap(res.pr, res.su), swap(u.pr, u.su), swap(v.pr, v.su);
	swap(u, v);
	res.pr = compress(res.pr); res.su = compress(res.su);
	return res;
}
struct SegTree
{
	int rt, idx;
	struct SGT
	{
		int ls, rs; Data data;
		#define ls(x) tree[x].ls
		#define rs(x) tree[x].rs
		#define data(x) tree[x].data
	} tree[N * 2];
	inline void pushup(int now)
	{data(now) = data(ls(now)) + data(rs(now));}
	inline void build(int &now, int l, int r)
	{
		now = ++idx;
		if(l == r) {data(now).unit(l); return ;}
		int mid = (l + r) >> 1;
		build(ls(now), l, mid), build(rs(now), mid + 1, r);
		pushup(now);
//		cerr << "build " << l << " " << r << " ++++++++++++++++++++++++++++++++++++++\n";
//		data(now).debug();
	}
	inline void modify(int now, int l, int r, int pos)
	{
		if(l == r) return ;
		int mid = (l + r) >> 1;
		if(pos <= mid) modify(ls(now), l, mid, pos);
		else modify(rs(now), mid + 1, r, pos);
		pushup(now);
	}
	inline Data query(int now, int l, int r, int L, int R)
	{
		if(L <= l && r <= R) return data(now);
		int mid = (l + r) >> 1;
		Data res;
		if(R <= mid) res = query(ls(now), l, mid, L, R);
		else if(mid < L) res = query(rs(now), mid + 1, r, L, R);
		else res = (query(ls(now), l, mid, L, R) + query(rs(now), mid + 1, r, L, R));
//		cerr << "query " << l << " " << r << " ++++++++++++++++++++\n";
//		res.debug();
		return res;
	}
	
	inline void _init() {build(rt, 1, n);}
	inline void _modify(int p) {modify(rt, 1, n, p);}
	inline Data _query(int l, int r) {return query(rt, 1, n, l, r);}
}; SegTree sgt;

int main()
{
//	freopen("text.in", "r", stdin);
//	freopen("prog.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> s; n = s.length(); s = ' ' + s;
	pw[0] = 1; for(int i = 1; i <= n; ++i) pw[i] = (__int128)pw[i - 1] * P % mod;
	blocks._setup(); sgt._init();
	cin >> m;
	for(int i = 1, lst; i <= m; ++i)
	{
		int opt, l, r, p; char c; cin >> opt;
		if(opt == 1)
		{
			cin >> p >> c;
//			p ^= lst;
			s[p] = c; blocks._modify(p), sgt._modify(p);
		}
		else
		{
			cin >> l >> r;
//			l ^= lst, r ^= lst;
			lst = 0; Data dt = sgt._query(l, r);
			for(Seq sq : dt.su) lst += sq.l;
			cout << lst << '\n';
		}
	}
	return 0;
}
/*
abbaaabaac
1
2 1 7
*/

詳細信息

Subtask #1:

score: 0
Memory Limit Exceeded

Test #1:

score: 0
Memory Limit Exceeded

input:

aabbbabbbaaaaaaabbabbbaaaabaaaabbaabbaabbaaababbbabbbbabbbbaaaabbbabbbbbaaabbbabbaaaaabbbbbaaababbabbaaaaabaabbbbaaababaaabbaabbabbbabbbbaaaaabbbbbbbabbbaabbbabbabbbababbabbbbaaaaabbaababbbbaabbaaaaaabaaabbbaaababbbbaabaaaaababababbbbbbaaaabbbbaaababaaabbaabbbbbaaaabbaaaabaaaaaababbababaaaabaaababaa...

output:


result:


Subtask #2:

score: 0
Memory Limit Exceeded

Test #15:

score: 0
Memory Limit Exceeded

input:

aabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbbaaabbaabbbbaabbaaabbbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbaaabaaaaaabaaabbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabb...

output:

41
45
153
119
60
167
50
166
118
204
148
143
29
70
118
123
159
10
105
307
101
74
37
362
78
182
55
34
84
263
72
112
79
192
152
153
155
50
130
137
142
26
308
9
12
258
257
137
356
49
115
332
17
126
19
35
117
157
40
93
285
90
351
168
61
150
46
181
102
283
166
24
84
177
32
123
64
125
282
22
81
213
120
144...

result:


Subtask #3:

score: 0
Time Limit Exceeded

Test #21:

score: 0
Time Limit Exceeded

input:

abbaaaabbabaaaaaabaabbaabbababbaaabbabbbabaabaabaaaaabaabbbbabbabbabbbababbbababababbbbabaabbaaababbbbbababbbbaabbbaaabaababababaabbbbbbaababaabbaaabaabbaaababbabbabbbbaaaaabaaabbbabbbbbbabbbabbabaabbbbbbbaaaabbaaaababbbaaaaaaababaabbbbaaabaaabbaabbbbbbababbaabbaaabbabbbbbabaababbaabaaaabbbbabababba...

output:


result:


Subtask #4:

score: 0
Time Limit Exceeded

Test #27:

score: 0
Time Limit Exceeded

input:

babbaaabbbbbbbabbbababaabbbbbababababbaabaabbbbbbabbbbbbbbbbababbbbabbaabbbaabaabbabbbaabbabbbabbababaababbbabbbbaabbabbabbaaaabbbaaabbbbaabbaaaaaaabbbabbbaaabaababaaabaaaabaaaababaaaaababaaaabaabbaaaabbbabbaabaabbbabbbbbaaabaababbbaaaaabbbbaaabbbbaabbabbbbabbbabbaaaaabaabaaaabbbabbbbbaabbbbabbbbaab...

output:

4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
...

result:


Subtask #5:

score: 0
Skipped

Dependency #1:

0%

Subtask #6:

score: 0
Skipped

Dependency #1:

0%