QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#219262#5037. 回文chenxinyang20060 0ms0kbC++149.0kb2023-10-19 10:23:402023-10-19 10:23:40

Judging History

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

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

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;
	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});
			}
		}
	}
	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";
	__frp = 0;
/*	if(p.l == 4 && q.r == 10){
		__frp = 1;
		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";
	}*/
	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){
	result.l = result.r = 0;
	query(1,1,n,l,r);
	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;
}

详细

Subtask #1:

score: 0
Runtime Error

Test #1:

score: 0
Runtime Error

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:


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%