QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#219381 | #5037. 回文 | chenxinyang2006 | 0 | 4776ms | 70080kb | C++14 | 14.7kb | 2023-10-19 13:58:10 | 2023-10-19 13:58:11 |
Judging History
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;
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++;
}
curL = l;curR = r;
rev = 0;
for(info I:result.suf){
if(!I.d) I.d = 114514;
int pos = I.l;
while(pos <= I.r){
assert(check(pos,r));
printf("%d\n",pos);
pos += I.d;
}
}
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
Wrong Answer
Test #1:
score: 0
Wrong Answer
time: 30ms
memory: 43328kb
input:
aabbbabbbaaaaaaabbabbbaaaabaaaabbaabbaabbaaababbbabbbbabbbbaaaabbbabbbbbaaabbbabbaaaaabbbbbaaababbabbaaaaabaabbbbaaababaaabbaabbabbbabbbbaaaaabbbbbbbabbbaabbbabbabbbababbabbbbaaaaabbaababbbbaabbaaaaaabaaabbbaaababbbbaabaaaaababababbbbbbaaaabbbbaaababaaabbaabbbbbaaaabbaaaabaaaaaababbababaaaabaaababaa...
output:
4778 4779 2 1672 1673 1674 3 4396 4397 4398 4399 4400 5 4359 4361 4355 3 3462 3463 3464 3 4180 4181 4177 3 4914 4918 2 4561 4563 4565 3 3822 3823 3824 3825 4 3742 3745 2 3608 3609 3610 3611 4 3461 3465 2 4214 4215 4216 4217 4 4782 4786 2 4681 4683 4671 3 3204 3205 3206 3 4768 4769 4770 3 4420 4424 2...
result:
wrong answer 1st words differ - expected: '2', found: '4778'
Subtask #2:
score: 0
Wrong Answer
Test #15:
score: 0
Wrong Answer
time: 4776ms
memory: 70080kb
input:
aabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbbaaabbaabbbbaabbaaabbbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabbababaabbaaabaaaaaabaaabbaabababbabbbbbbabbababaaaabababbabbbbbbabbababaaaabababbabbbbbbabb...
output:
48380 48381 48382 48369 48376 32169 32619 33069 33519 33969 34419 34869 35319 35769 36219 36669 37119 37569 38019 38469 38919 39369 39819 40269 40719 41169 41619 42069 42519 42969 43419 43869 44319 44769 45219 45669 46119 46569 47019 47469 47919 41 116047 116049 116008 116032 115702 115936 99052 995...
result:
wrong answer 1st words differ - expected: '41', found: '48380'
Subtask #3:
score: 0
Wrong Answer
Test #21:
score: 0
Wrong Answer
time: 1729ms
memory: 69352kb
input:
abbaaaabbabaaaaaabaabbaabbababbaaabbabbbabaabaabaaaaabaabbbbabbabbabbbababbbababababbbbabaabbaaababbbbbababbbbaabbbaaabaababababaabbbbbbaababaabbaaabaabbaaababbabbabbbbaaaaabaaabbbabbbbbbabbbabbabaabbbbbbbaaaabbaaaababbbaaaaaaababaabbbbaaabaaabbaabbbbbbababbaabbaaabbabbbbbabaababbaabaaaabbbbabababba...
output:
199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 199999 2 199997 19999...
result:
wrong answer 1st words differ - expected: '2', found: '199997'
Subtask #4:
score: 0
Wrong Answer
Test #27:
score: 0
Wrong Answer
time: 964ms
memory: 69276kb
input:
babbaaabbbbbbbabbbababaabbbbbababababbaabaabbbbbbabbbbbbbbbbababbbbabbaabbbaabaabbabbbaabbabbbabbababaababbbabbbbaabbabbabbaaaabbbaaabbbbaabbaaaaaaabbbabbbaaabaababaaabaaaabaaaababaaaaababaaaabaabbaaaabbbabbaabaabbbabbbbbaaabaababbbaaaaabbbbaaabbbbaabbabbbbabbbabbaaaaabaabaaaabbbabbbbbaabbbbabbbbaab...
output:
199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 199999 200000 199988 199996 4 ...
result:
wrong answer 1st words differ - expected: '4', found: '199999'
Subtask #5:
score: 0
Skipped
Dependency #1:
0%
Subtask #6:
score: 0
Skipped
Dependency #1:
0%