Codechef CBAF(分塊)
阿新 • • 發佈:2018-12-14
題解: 分塊SB題。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=getchar(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=getchar();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=getchar();}
return i*f;
}
inline void W(LL x) {
static int buf[50];
if(!x) {putchar('0'); return;}
if(x<0) {putchar('-'); x=-x;}
while (x) {buf[++buf[0]]=x%10; x/=10;}
while(buf[0]) {putchar(buf[buf[0]--]+'0');}
}
const int N=1e5+50, S=534;
char ch[N];
int n,a[N],bl[N],bg[N],ed[N],h;
LL sum[3][N/S+1][N];
LL ans[3][N/S+1][N];
inline void init() {
scanf("%s",ch+1); n=strlen(ch+1);
for(int i=1;i<=n;i++) a[i]=a[i-1]^(1<<(ch[ i]-'a'));
vector <int> vec;
for(int i=0;i<=n;i++) vec.push_back(a[i]);
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());
for(int i=0;i<=n;i++) a[i]=lower_bound(vec.begin(),vec.end(),a[i])-vec.begin();
}
struct BL {
LL s[N]; int vis[N],vt;
inline void init() {++vt;}
inline void inc(int pos,LL val) {(vis[pos]==vt) ? (s[pos]+=val) : (vis[pos]=vt, s[pos]=val);}
inline LL ask(int pos) {return (vis[pos]==vt) ? s[pos] : 0;}
} s[3];
inline LL ask(int type,int L,int R,int ai) {return sum[type][R][ai]-sum[type][L-1][ai]+s[type].ask(ai);}
inline LL solve(int l,int r,int type) {
s[0].init(); s[1].init(); s[2].init();
LL val=0;
if(r-l+1<=2*S) {
for(int i=l-1;i<r;) {
if(type>=0) s[0].inc(a[i],1);
if(type>=1) s[1].inc(a[i],i);
if(type>=2) s[2].inc(a[i],(LL)i*i);
i++;
if(type==0) val+=s[0].ask(a[i]);
if(type==1) val+=s[0].ask(a[i])*i-s[1].ask(a[i]);
if(type==2) val+=s[0].ask(a[i])*i*i-2*s[1].ask(a[i])*i+s[2].ask(a[i]);
}
} else {
int L=bl[l]+1, R=bl[r]-1; val=ans[type][L][R];
for(int i=bg[L]-1;i>=l;) {
s[0].inc(a[i],1);
s[1].inc(a[i],i);
s[2].inc(a[i],(LL)i*i);
i--;
val+=(type==0) ? ask(0,L,R,a[i]) :
((type==1) ? (ask(1,L,R,a[i])-ask(0,L,R,a[i])*i) : (ask(2,L,R,a[i])-2*ask(1,L,R,a[i])*i+ask(0,L,R,a[i])*i*i));
}
s[0].inc(a[l-1],1); s[1].inc(a[l-1],l-1); s[2].inc(a[l-1],(LL)(l-1)*(l-1));
for(int i=ed[R]+1;i<=r;i++) {
val+=(type==0) ? ask(0,L,R,a[i]) :
((type==1) ? (ask(0,L,R,a[i])*i-ask(1,L,R,a[i])) : (ask(0,L,R,a[i])*i*i-2*ask(1,L,R,a[i])*i+ask(2,L,R,a[i])));
s[0].inc(a[i],1); s[1].inc(a[i],i); s[2].inc(a[i],(LL)i*i);
}
} return val;
}
inline void pre_calc() {
h=0;
for(int i=1,j;i<=n;i=j+1) {
j=min(i+S,n);
bg[++h]=i; ed[h]=j;
for(int k=i;k<=j;k++) bl[k]=h;
}
for(int i=1;i<=h;i++) {
LL val[3];
s[0].init(); s[1].init(); s[2].init();
val[0]=val[1]=val[2]=0;
for(int j=i,r=bg[i]-1;j<=h;j++) {
while(r<ed[j]) {
s[0].inc(a[r],1);
s[1].inc(a[r],r);
s[2].inc(a[r],(LL)r*r);
r++;
val[0]+=s[0].ask(a[r]);;
val[1]+=s[0].ask(a[r])*r-s[1].ask(a[r]);
val[2]+=s[0].ask(a[r])*r*r-2*s[1].ask(a[r])*r+s[2].ask(a[r]);
}
ans[0][i][j]=val[0];
ans[1][i][j]=val[1];
ans[2][i][j]=val[2];
}
}
for(int i=1;i<=h;i++) {
for(int j=0;j<=2;j++) memcpy(sum[j][i],sum[j][i-1],sizeof(sum[j][i]));
for(int j=bg[i];j<=ed[i];j++) {
sum[0][i][a[j]]++;
sum[1][i][a[j]]+=j;
sum[2][i][a[j]]+=(LL)j*j;
}
}
}
inline void solve() {
init();
pre_calc();
int A=0, B=0;
int Q=rd();
while(Q--) {
int x=rd(), y=rd(), type=rd();
int l=(x+A)%n+1, r=(y+B)%n+1;
if(l>r) swap(l,r);
LL ans=solve(l,r,type);
W(ans); putchar('\n');
A=B; B=ans%n;
}
}
int main() {
for(int i=rd();i;i--) solve();
}