QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#219262 | #5037. 回文 | chenxinyang2006 | 0 | 0ms | 0kb | C++14 | 9.0kb | 2023-10-19 10:23:40 | 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%