版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35649707/article/details/82747316
题解:
直接暴力SG函数求解即可。 可以证明有用区间只有 个。
#include <bits/stdc++.h>
using namespace std;
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=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const int N=1e5+50;
char ch[N];
int n,a[N],pre[N][26],suf[N][26];
int f[N][26],g[N],mem[27];
inline int mex(int sta) {return __builtin_ctz(~sta);}
inline int calc(int l,int r,int c,int flag) {
if(l>r) return 0;
if(~mem[c]) return mem[c];
int sta=0;
for(int j=0;j<26;++j) {
int _l=suf[l][j], _r=pre[r][j];
if(_r>=l) sta|=1<<(g[_r]^g[_l]^(!flag ? f[_l-1][c] : calc(l,_l-1,j,1))^(flag ? f[r][j] : calc(_r+1,r,j,0)));
}
return mem[c]=mex(sta);
}
int main() {
scanf("%s",ch+1); n=strlen(ch+1);
for(int i=1;i<=n;i++) a[i]=ch[i]-'a';
for(int i=1;i<=n;i++) {
for(int j=0;j<26;++j) pre[i][j]=pre[i-1][j];
pre[i][a[i]]=i;
}
for(int j=0;j<26;++j) suf[n+1][j]=n+1;
for(int i=n;i>=1;i--) {
for(int j=0;j<26;++j) suf[i][j]=suf[i+1][j];
suf[i][a[i]]=i;
}
for(int i=1;i<=n;i++) {
g[i]=f[i-1][a[i]]^g[pre[i-1][a[i]]];
memset(mem,-1,sizeof(mem));
for(int j=0;j<26;++j) f[i][j]=calc(pre[i][j]+1,i,j,0);
}
int q=rd();
for(int i=1;i<=q;i++) {
int l=rd(), r=rd();
memset(mem,-1,sizeof(mem));
if(calc(l,r,26,1)) puts("Alice");
else puts("Bob");
}
}