QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#219269 | #5037. 回文 | chenxinyang2006 | 0 | 27ms | 37452kb | C++14 | 9.1kb | 2023-10-19 10:40:59 | 2023-10-19 10:40:59 |
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 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%