QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#219386#5037. 回文chenxinyang20060 0ms0kbC++1414.4kb2023-10-19 14:00:572023-10-19 14:00:58

Judging History

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

  • [2023-10-19 14:00:58]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2023-10-19 14:00:57]
  • 提交

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 998244853
//#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);
}

template <int P>
class mod_int
{
    using Z = mod_int;

private:
    static int mo(int x) { return x < 0 ? x + P : x; }

public:
    int x;
    int val() const { return x; }
    mod_int() : x(0) {}
    template <class T>
    mod_int(const T &x_) : x(x_ >= 0 && x_ < P ? static_cast<int>(x_) : mo(static_cast<int>(x_ % P))) {}
    bool operator==(const Z &rhs) const { return x == rhs.x; }
    bool operator!=(const Z &rhs) const { return x != rhs.x; }
    Z operator-() const { return Z(x ? P - x : 0); }
    Z pow(long long k) const
    {
        Z res = 1, t = *this;
        while (k)
        {
            if (k & 1)
                res *= t;
            if (k >>= 1)
                t *= t;
        }
        return res;
    }
    Z &operator++()
    {
        x < P - 1 ? ++x : x = 0;
        return *this;
    }
    Z &operator--()
    {
        x ? --x : x = P - 1;
        return *this;
    }
    Z operator++(int)
    {
        Z ret = x;
        x < P - 1 ? ++x : x = 0;
        return ret;
    }
    Z operator--(int)
    {
        Z ret = x;
        x ? --x : x = P - 1;
        return ret;
    }
    Z inv() const { return pow(P - 2); }
    Z &operator+=(const Z &rhs)
    {
        (x += rhs.x) >= P && (x -= P);
        return *this;
    }
    Z &operator-=(const Z &rhs)
    {
        (x -= rhs.x) < 0 && (x += P);
        return *this;
    }
    Z operator-()
    {
        return -x;
    }
    Z &operator*=(const Z &rhs)
    {
        x = 1ULL * x * rhs.x % P;
        return *this;
    }
    Z &operator/=(const Z &rhs) { return *this *= rhs.inv(); }
#define setO(T, o)                                  \
    friend T operator o(const Z &lhs, const Z &rhs) \
    {                                               \
        Z res = lhs;                                \
        return res o## = rhs;                       \
    }
    setO(Z, +) setO(Z, -) setO(Z, *) setO(Z, /)
#undef setO
    
    friend istream& operator>>(istream& is, mod_int& x)
    {
        long long tmp;
        is >> tmp;
        x = tmp;
        return is;
    }
    friend ostream& operator<<(ostream& os, const mod_int& x)
    {
        os << x.val();
        return os;
    }
};

using Z = mod_int<mod>;
Z power(Z p,ll k){
    Z ans = 1;
    while(k){
        if(k % 2 == 1) ans *= p;
        p *= p;
        k /= 2;
    }
    return ans;
}

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];
Z eP[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][550];
Z eval[2][300005],etag[2][550];
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];

	rep(i,1,n) eval[0][i] = eval[0][i - 1] + eP[0][i] * s[i];
	rep(i,1,n) eval[1][i] = eval[1][i - 1] + eP[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 eupd(int op,int pos,Z C){
	int fp = from(pos);
	rep(k,pos,R(fp)) eval[op][k] += C;
	rep(k,fp + 1,from(n)) etag[op][k] += C;	
}

Z eqry(int op,int pos){
	return eval[op][pos] + etag[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);

	eupd(0,pos,eP[0][pos] * C);
	eupd(1,n - pos + 1,eP[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];
}

//
Z _egetval(int l,int r){
	return (eqry(0,r) - eqry(0,l - 1)) * eP[1][l];	
}

Z _egetvalrev(int l,int r){
	l = n - l + 1;r = n - r + 1;
	swap(l,r);
	return (eqry(1,r) - eqry(1,l - 1)) * eP[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)) && (_egetval(l,r) == _egetvalrev(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);
}

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

	if(rev) return _egetvalrev(n - r + 1,n - l + 1);
	return _egetval(l,r);
}

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

	if(rev) return _egetval(n - r + 1,n - l + 1);
	return _egetvalrev(l,r);
}

Z egetval2(int l,int d){
	return egetval(l,l + d - 1);
}

Z egetvalrev2(int r,int d){
	return egetvalrev(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[530005];
#define ls (rt * 2)
#define rs (rt * 2 + 1)

int __frp;
int m;
info tmp[205];
void maintain(vector <info> &S){
	m = 0;
	if(__frp){
		cerr << "before maintain\n";
		for(info I:S) cerr << I.l << " " << I.r << " " << I.d << endl;
	}


	for(info I:S){
		if(I.l == I.r) I.d = 0;
		if(!m){
			tmp[++m] = I;
			continue;
		}
		if(!tmp[m].d || tmp[m].d == tmp[m].l - I.r){
			tmp[m].d = tmp[m].l - I.r;
			tmp[m].l = I.r;
			if(I.d) I.r -= I.d;
			else continue;
			if(I.l == I.r) I.d = 0;
		}else{
			tmp[++m] = I;
			continue;
		}
//		cerr << "tm\n";
//		cerr << I.l << " " << I.r << " " << I.d << endl;
		if(tmp[m].l - I.r == tmp[m].d){
			tmp[m].l = I.l;
			continue;
		}else{
			tmp[++m] = I;
		}
	}
	S.clear();
	rep(i,1,m) S.eb(tmp[i]);

	if(__frp){
		cerr << "result:\n";
		rep(i,1,m) cerr << tmp[i].l << " " << tmp[i].r << " " << tmp[i].d << endl;		
	}

}

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) && egetval(I.l + 1,I.l + 1 + pr - pl) == egetval(pl,pr)){//[pl,pr] 是 [I.l + 1,I.l + I.d] 的前缀
			pos = 0;
//			if(__frp) cerr << p.r << " " << I.l + 1 << endl;
			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) && egetvalrev2(p.r,(pos + (1 << _k)) * I.d) == egetval2(I.l + 1,(pos + (1 << _k)) * I.d)) pos += 1 << _k;
//			if(__frp) cerr << getvalrev2(8,6) << " " << getval2(10,6) << endl << "!!" << pos << endl;
//			if(__frp) cerr << "prefix! " << pos << endl;
			if(pl > pr || (getvalrev2(p.r - pos * I.d,pr - pl + 1) == getval(pl,pr) && egetvalrev2(p.r - pos * I.d,pr - pl + 1) == egetval(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) && egetvalrev2(p.r,(pos + (1 << _k)) * I.d) == egetval2(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) && egetvalrev2(I.r - 1,(pos + (1 << _k)) * I.d) == egetval2(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) && egetvalrev2(I.r - 1,pr - pl + 1) == egetval(pl,pr)){
			if(__frp) cerr << "!!" << pos << endl;
			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});
		}
	}
/*	if(__frp){
		cerr << "result:\n";
		for(info I:answer) cerr << I.l << " " << I.r << " " << I.d << endl;		
	}*/
	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;
//	if(p.l == 2 && q.r == 15) __frp = 1;
//	else __frp = 0;
	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";
	}*/
//	__frp = 0;
	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 vertify(int rt,int l,int r){
	rev = 0;
	curL = l;curR = r;
	for(info I:tree[rt].pre){
		if(!I.d) I.d = 114514;
		int pos = I.l;
		while(pos <= I.r){
			assert(l <= pos && pos <= r);
			if(!check(l,pos)) printf("fail vertify!! [%d,%d] %d %d\n",l,r,l,pos);
			assert(check(l,pos));
			pos += I.d;
		}
	}
	for(info I:tree[rt].suf){
		if(!I.d) I.d = 114514;
		int pos = I.r;
		while(pos >= I.l){
			assert(l <= pos && pos <= r);
			if(!check(pos,r)) printf("fail vertify!! [%d,%d]\n",l,r);
			assert(check(pos,r));
			pos -= I.d;
		}
	}
}

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];
//	vertify(rt,l,r);
//	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;
	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;
	eP[0][0] = eP[1][0] = 1;
	rep(i,1,n){
		P[0][i] = P[0][i - 1] * base;
		P[1][i] = P[1][i - 1] * ibase;

		eP[0][i] = eP[0][i - 1] * base;
		eP[1][i] = eP[1][i - 1] / base;
	}
	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: 0
Runtime Error

input:

aabbbabbbaaaaaaabbabbbaaaabaaaabbaabbaabbaaababbbabbbbabbbbaaaabbbabbbbbaaabbbabbaaaaabbbbbaaababbabbaaaaabaabbbbaaababaaabbaabbabbbabbbbaaaaabbbbbbbabbbaabbbabbabbbababbabbbbaaaaabbaababbbbaabbaaaaaabaaabbbaaababbbbaabaaaaababababbbbbbaaaabbbbaaababaaabbaabbbbbaaaabbaaaabaaaaaababbababaaaabaaababaa...

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%