QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#219269#5037. 回文chenxinyang20060 27ms37452kbC++149.1kb2023-10-19 10:40:592023-10-19 10:40:59

Judging History

你现在查看的是最新测评结果

  • [2023-10-19 10:40:59]
  • 评测
  • 测评结果:0
  • 用时:27ms
  • 内存:37452kb
  • [2023-10-19 10:40:59]
  • 提交

answer

#include <bits/stdc++.h>
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define per(i,j,k) for(int i=(j);i>=(k);i--)
#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define db double
#define ldb long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define mkp make_pair
#define eb emplace_back
#define SZ(S) (int)S.size()
//#define mod 998244353
//#define mod 1000000007
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3f
using namespace std;

template <class T>
void chkmax(T &x,T y){
	if(x < y) x = y;
}

template <class T>
void chkmin(T &x,T y){
	if(x > y) x = y;
}

inline int popcnt(int x){
	return __builtin_popcount(x);
}

inline int ctz(int x){
	return __builtin_ctz(x);
}
ull seed = 'x' + 'a' + 'y' + 't' + 'x' + 'd' + 'y';
ull rnd(){
	seed = seed * 1145141 + 1011451423;
	return seed;
}

int n,Q;
char s[200005];
ull P[2][200005];

#define base 127
#define ibase 9150747060186627967llu

const int B = 447;
inline int from(int x){return (x + B - 1) / B;}
inline int L(int x){return x * B - B + 1;}
inline int R(int x){return x * B;}
ull val[2][300005],tag[2][450];
void init(){
	rep(i,1,n) val[0][i] = val[0][i - 1] + P[0][i] * s[i];
	rep(i,1,n) val[1][i] = val[1][i - 1] + P[0][i] * s[n + 1 - i];
}

void upd(int op,int pos,ull C){
	int fp = from(pos);
	rep(k,pos,R(fp)) val[op][k] += C;
	rep(k,fp + 1,from(n)) tag[op][k] += C;
}

ull qry(int op,int pos){
	return val[op][pos] + tag[op][from(pos)];
}

void mdf(int pos,int C){
	upd(0,pos,P[0][pos] * C);
	upd(1,n - pos + 1,P[0][n - pos + 1] * C);
}

int rev;//rev 表示查询的都是反信息
int curL,curR;
ull _getval(int l,int r){
	return (qry(0,r) - qry(0,l - 1)) * P[1][l];
}

ull _getvalrev(int l,int r){
	l = n - l + 1;r = n - r + 1;
	swap(l,r);
	return (qry(1,r) - qry(1,l - 1)) * P[1][l];
}

int check(int l,int r){
	if(l < curL || r > curR) return 0;
	if(rev){
		l = n - l + 1;r = n - r + 1;
		swap(l,r);
	}
	return (_getval(l,r) == _getvalrev(l,r));
}

ull getval(int l,int r){
	if(l < curL || r > curR) return rnd();

	if(rev) return _getvalrev(n - r + 1,n - l + 1);
	return _getval(l,r);
}

ull getvalrev(int l,int r){
	if(l < curL || r > curR) return rnd();

	if(rev) return _getval(n - r + 1,n - l + 1);
	return _getvalrev(l,r);
}

ull getval2(int l,int d){
	return getval(l,l + d - 1);
}

ull getvalrev2(int r,int d){
	return getvalrev(r - d + 1,r);
}

int check2(int l,int r){//拓展到右端点 curR
	return check(l + r - curR,curR);
}

struct info{
	int l,r,d;
};

struct node{
	vector <info> pre,suf;//维护所有起始终止点
	int l,r;
}tree[510005];
#define ls (rt * 2)
#define rs (rt * 2 + 1)

int m;
info tmp[205];
void maintain(vector <info> &S){
	m = 0;
	int flg,dd;
	for(info I:S){
		if(I.l == I.r) I.d = 0;
		if(!m){
			tmp[++m] = I;
			continue;
		}
		flg = 0;
		dd = tmp[m].d | I.d;
		if(tmp[m].d && tmp[m].d != dd) flg = 1;
		if(I.d && I.d != dd) flg = 1;
		if(tmp[m].l - I.r != dd) flg = 1;
		if(!dd) flg = 0;

		if(flg){
			tmp[++m] = I;
			continue;
		}
		tmp[m].d |= tmp[m].l - I.r;
		tmp[m].l = I.l;
	}
	S.clear();
	rep(i,1,m) S.eb(tmp[i]);
}

int __frp;
vector <info> answer;
void mrg(node &p,node &q){
	assert(p.r + 1 == q.l);
	if(__frp){
		cerr << '[' << p.l << "," << p.r << "] [" << q.l << "," << q.r << "]\n";
		cerr << "psuf\n";
		for(info I:p.suf) cerr << I.l << " " << I.r << " " << I.d << endl;
		cerr << "qpre\n";
		for(info I:q.pre) cerr << I.l << " " << I.r << " " << I.d << endl;
		cerr << "qsuf\n";
		for(info I:q.suf) cerr << I.l << " " << I.r << " " << I.d << endl;		
	}


	answer = q.suf;
	info cur = answer.back();
	if(cur.l == q.l){
		if(cur.l == cur.r){
			answer.pop_back();
		}else{
			cur.l += cur.d;
			answer.pop_back();
			answer.eb(cur);
		}
	}

	curL = p.l;curR = q.r;
	int pl,pr,k,pos;
	reverse(q.pre.begin(),q.pre.end());
	for(info I:q.pre){
		if(I.l == I.r){
			pl = q.l - (q.r - I.l);
			pr = q.r;
//			if(__frp) cerr << "check range" << pl << " " << pr << endl;
			if(check(pl,pr)) answer.push_back({pl,pl,0});
			continue;
		}
		k = (I.r - I.l) / I.d;
		pl = I.r + 1;pr = q.r;
		if(pr - pl + 1 <= I.d && getval(I.l + 1,I.l + 1 + pr - pl) == getval(pl,pr)){//[pl,pr] 是 [I.l + 1,I.l + I.d] 的前缀
			pos = 0;
			per(_k,__lg(k),0) if(pos + (1 << _k) <= k && getvalrev2(p.r,(pos + (1 << _k)) * I.d) == getval2(I.l + 1,(pos + (1 << _k) * I.d))) pos += 1 << _k;
			if(__frp) cerr << "prefix! " << pos << endl;
			if(pl > pr || getvalrev2(p.r - pos * I.d,pr - pl + 1) == getval(pl,pr)) pos++;
			pos--;
			pos = k - pos;
			if(__frp) cerr << pos << endl;
			if(pos <= k) answer.push_back({q.l + I.l - q.r + pos * I.d,q.l + I.l - q.r + k * I.d,I.d});
		}else{
			pos = 0;
			per(_k,__lg(k),0) if(pos + (1 << _k) <= k && getvalrev2(p.r,(pos + (1 << _k)) * I.d) == getval2(I.l + 1,(pos + (1 << _k)) * I.d)) pos += 1 << _k;
			if(check2(q.l,I.l + I.d * (k - pos))){
				pl = q.l + I.l + I.d * (k - pos) - q.r;
				answer.push_back({pl,pl,0});
			}
		}
	}
	reverse(q.pre.begin(),q.pre.end());
	if(check2(p.r,q.l)){
		pl = p.r + q.l - q.r;
		answer.push_back({pl,pl,0});
	}
	if(__frp){
		cerr << "partical result:\n";
		for(info I:answer) cerr << I.l << " " << I.r << " " << I.d << endl;		
	}
	for(info I:p.suf){
		if(I.l == I.r){
			pl = I.l + p.r - q.r;
			pr = q.r;
//			cerr << "check " << pl << " " << pr << endl;
			if(check(pl,pr)) answer.push_back({pl,pl,0});
			continue;
		}
		k = (I.r - I.l) / I.d;
		pos = 0;
		per(_k,__lg(k),0) if(pos + (1 << _k) <= k && getvalrev2(I.r - 1,(pos + (1 << _k)) * I.d) == getval2(q.l,(pos + (1 << _k)) * I.d)) pos += 1 << _k;
		pl = q.l + pos * I.d;
		pr = q.r;
		if(pr - pl + 1 <= I.d && getvalrev2(I.r - 1,pr - pl + 1) == getval(pl,pr)){
			if(k - pos > 0) answer.push_back({I.r - (k - pos - 1) * I.d + p.r - q.r,I.r + p.r - q.r,I.d});
		}

		if(check2(I.r - (k - pos) * I.d,p.r)){
			pl = I.r - (k - pos) * I.d + p.r - q.r;
			answer.push_back({pl,pl,0});
		}
	}
	maintain(answer);
	if(__frp){
		cerr << "result:\n";
		for(info I:answer) cerr << I.l << " " << I.r << " " << I.d << endl;		
	}
}

void rever(vector <info> &p){
	for(info &I:p){
		I.l = n + 1 - I.l;
		I.r = n + 1 - I.r;
		swap(I.l,I.r);
	}
}

node operator +(node &p,node &q){
	node ans;
	rev = 0;
	ans.l = curL = p.l;ans.r = curR = q.r;
//	cerr << "merge suffix\n";
	if(__frp) cerr << "merge suffix:\n";
	mrg(p,q);
	ans.suf = answer;
	
//	__frp = 0;
/*	if(p.l == 1 && q.r == 4){
		__frp = 1;
		cerr << "merge prefix:\n";
	}*/
	if(__frp) cerr << "merge prefix:\n";
	node tp = p,tq = q;
	rever(tp.pre);rever(tp.suf);
	rever(tq.pre);rever(tq.suf);
	swap(tp.pre,tq.suf);
	swap(tp.suf,tq.pre);
	tp.l = n + 1 - tp.l;tp.r = n + 1 - tp.r;
	tq.l = n + 1 - tq.l;tq.r = n + 1 - tq.r;
	swap(tp.l,tq.r);swap(tp.r,tq.l);
	rev = 1;
	mrg(tp,tq);

	rever(answer);
	ans.pre = answer;
	return ans;
}

void print(node &p){
	cerr << "range [" << p.l << "," << p.r << "] info\n";
	cerr << "pre palin\n";
	for(info I:p.pre) cerr << I.l << " " << I.r << " " << I.d << endl;
	cerr << "suf palin\n";
	for(info I:p.suf) cerr << I.l << " " << I.r << " " << I.d << endl; 
}

void build(int rt,int l,int r){
	if(l == r){
		tree[rt].l = tree[rt].r = l;
		tree[rt].pre.push_back({l,l,0});
		tree[rt].suf.push_back({l,l,0});
//		print(tree[rt]);
		return;
	}
	int mid = (l + r) >> 1;
	build(ls,l,mid);build(rs,mid+1,r);
	tree[rt] = tree[ls] + tree[rs];
//	print(tree[rt]);
}

void modify(int rt,int l,int r,int pos){
	if(l == r){
		tree[rt].l = tree[rt].r;
		tree[rt].pre.clear();tree[rt].suf.clear();
		tree[rt].pre.push_back({l,l,0});
		tree[rt].suf.push_back({l,l,0});
		return;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid) modify(ls,l,mid,pos);
	else modify(rs,mid+1,r,pos);
	tree[rt] = tree[ls] + tree[rs];
}

node result;
void query(int rt,int l,int r,int L,int R){
	if(l == L && r == R){
		if(!result.l) result = tree[rt];
		else result = result + tree[rt];
		return;
	}
	int mid = (l + r) >> 1;
	if(R <= mid){
		query(ls,l,mid,L,R);
	}else if(L > mid){
		query(rs,mid+1,r,L,R);
	}else{
		query(ls,l,mid,L,mid);
		query(rs,mid+1,r,mid+1,R);
	}
}

int solve(int l,int r){
//	__frp = 1;
	result.l = result.r = 0;
	query(1,1,n,l,r);
//	__frp = 0;
	int _result = 0;
	for(info I:result.suf){
		if(I.d) _result += (I.r - I.l) / I.d + 1;
		else _result++;
	}
	return _result;
}

int main(){
//	freopen("test.in","r",stdin);
//	freopen("test.out","w",stdout);
	scanf("%s",s + 1);
	n = strlen(s + 1);
	P[0][0] = P[1][0] = 1;
	rep(i,1,n){
		P[0][i] = P[0][i - 1] * base;
		P[1][i] = P[1][i - 1] * ibase;
	}
	init();
	build(1,1,n);
//	printf("qwq\n");

	int lastans = 0,op,l,r;
	char ch;
	scanf("%d",&Q);
	rep(i,1,Q){
		scanf("%d",&op);
		if(op == 1){
			scanf("%d",&l);
			l ^= lastans;
			assert(1 <= l && l <= n);
			do{
				scanf("%c",&ch);
			}while(ch < 'a' || ch > 'z');
			mdf(l,ch - s[l]);
			s[l] = ch;
			modify(1,1,n,l);
		}else{
			scanf("%d%d",&l,&r);
			l ^= lastans;r ^= lastans;
			assert(1 <= l && l <= r && r <= n);
			lastans = solve(l,r);
			printf("%d\n",lastans);
		}
	}
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Runtime Error

Test #1:

score: 10
Accepted
time: 20ms
memory: 37452kb

input:

aabbbabbbaaaaaaabbabbbaaaabaaaabbaabbaabbaaababbbabbbbabbbbaaaabbbabbbbbaaabbbabbaaaaabbbbbaaababbabbaaaaabaabbbbaaababaaabbaabbabbbabbbbaaaaabbbbbbbabbbaabbbabbabbbababbabbbbaaaaabbaababbbbaabbaaaaaabaaabbbaaababbbbaabaaaaababababbbbbbaaaabbbbaaababaaabbaabbbbbaaaabbaaaabaaaaaababbababaaaabaaababaa...

output:

2
3
5
3
3
3
2
3
4
2
4
2
4
2
3
3
3
2
2
2
2
2
2
3
4
2
2
3
2
2
4
3
3
2
3
3
4
3
3
4
4
2
3
4
2
2
4
2
4
3
2
2
2
3
3
3
4
4
3
3
2
3
3
2
3
3
4
2
2
4
2
3
2
3
3
2
3
2
2
3
2
2
3
6
2
2
3
7
4
3
2
2
2
2
3
4
4
4
4
2
2
3
2
4
2
2
2
3
3
2
2
2
2
3
3
4
3
2
3
3
2
2
4
5
4
2
2
5
3
3
3
3
2
4
2
3
2
3
3
3
2
4
4
5
2
2
3
5
3
3
...

result:

ok 2509 tokens

Test #2:

score: 0
Accepted
time: 27ms
memory: 37160kb

input:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...

output:

188
1078
673
914
360
4255
2205
3628
77
3608
230
494
128
848
801
1335
4079
3059
636
2882
3524
45
1174
506
3570
4172
1289
595
3829
1532
179
1274
2574
1098
2817
226
2580
887
989
1829
3656
181
2056
3315
786
117
2519
2742
3787
1080
3138
686
1605
239
1533
2658
2096
753
3400
219
1815
117
1645
52
1671
121
2...

result:

ok 2519 tokens

Test #3:

score: -10
Runtime Error

input:

bbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbbbbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbbbbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbbbbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbbabbba...

output:


result:


Subtask #2:

score: 0
Runtime Error

Test #15:

score: 0
Runtime Error

input:

aabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbbaaabbaabbbbaabbaaabbbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbaaabaaaaaabaaabbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabb...

output:


result:


Subtask #3:

score: 0
Runtime Error

Test #21:

score: 0
Runtime Error

input:

abbaaaabbabaaaaaabaabbaabbababbaaabbabbbabaabaabaaaaabaabbbbabbabbabbbababbbababababbbbabaabbaaababbbbbababbbbaabbbaaabaababababaabbbbbbaababaabbaaabaabbaaababbabbabbbbaaaaabaaabbbabbbbbbabbbabbabaabbbbbbbaaaabbaaaababbbaaaaaaababaabbbbaaabaaabbaabbbbbbababbaabbaaabbabbbbbabaababbaabaaaabbbbabababba...

output:


result:


Subtask #4:

score: 0
Runtime Error

Test #27:

score: 0
Runtime Error

input:

babbaaabbbbbbbabbbababaabbbbbababababbaabaabbbbbbabbbbbbbbbbababbbbabbaabbbaabaabbabbbaabbabbbabbababaababbbabbbbaabbabbabbaaaabbbaaabbbbaabbaaaaaaabbbabbbaaabaababaaabaaaabaaaababaaaaababaaaabaabbaaaabbbabbaabaabbbabbbbbaaabaababbbaaaaabbbbaaabbbbaabbabbbbabbbabbaaaaabaabaaaabbbabbbbbaabbbbabbbbaab...

output:


result:


Subtask #5:

score: 0
Skipped

Dependency #1:

0%

Subtask #6:

score: 0
Skipped

Dependency #1:

0%