我们令子串 Ss,t 对应的 ws 为这个子串的 b
因为互质 所以 b 是互不相同的 转为求有几个 b 满足条件
然后每一位看作一个限制 把所有限制离散化取交即可 注意处理奇偶性
还有一个细节 s≤n−m+1 我们还要倒着把最后 m−1 个 b 中合法的减掉
#include
#include
#include
#include
#include
#define pb push_back
using namespace std;
typedef long long ll;
const int N=1000005;
int n,a,b,L,R;
int m; char t[N];
int tot;
int l[N<<2],r[N<<2]; bool e[N<<2];
inline void add(ll _L,ll _R,ll ax,int t){
if (_L>_R) return;
ll L=(_L+n-ax%n)%n,R=(_R+n-ax%n)%n;
if (L<=R){
l[++tot]=L,r[tot]=R;
e[tot]=t^((L&1)^(_L&1));
}else{
l[++tot]=0,r[tot]=R;
e[tot]=t^((R&1)^(_R&1));
l[++tot]=L,r[tot]=n-1;
e[tot]=t^((L&1)^(_L&1));
}
}
int sx[N<<3],icnt;
int idx[N<<3],cnt;
int T[N<<3][2];
inline bool cmp(int x,int y){
return (x>0?l[x]:r[-x])<(y>0?l[y]:r[-y]);
}
inline int calc(int l,int r,int t){
if (t==1){
if (~l&1) l++;
if (r&1) r++;
return (r-l+1)>>1;
}else{
if (l&1) l++;
if (~r&1) r++;
return (r-l+1)>>1;
}
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d%d%d%d%d",&n,&a,&b,&L,&R);
scanf("%s",t+1); m=strlen(t+1);
for (int i=1;i<=m;i++)
if (t[i]=='A'){
add(L,R,(ll)a*(i-1)%n,0);
}else if (t[i]=='T'){
add(L,R,(ll)a*(i-1)%n,1);
}
else if (t[i]=='G'){
add(0,L-1,(ll)a*(i-1)%n,0);
add(R+1,n-1,(ll)a*(i-1)%n,0);
}else if (t[i]=='C'){
add(0,L-1,(ll)a*(i-1)%n,1);
add(R+1,n-1,(ll)a*(i-1)%n,1);
}
sx[++icnt]=0; sx[++icnt]=n;
for (int i=1;i<=tot;i++){
sx[++icnt]=l[i],sx[++icnt]=r[i]+1;
}
sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1;
for (int i=1;i<=tot;i++){
l[i]=lower_bound(sx+1,sx+icnt+1,l[i])-sx;
r[i]=lower_bound(sx+1,sx+icnt+1,r[i]+1)-sx;
idx[++cnt]=i,idx[++cnt]=-i;
}
sort(idx+1,idx+cnt+1,cmp);
ll t[2]={0,0}; int pnt=1;
ll ans=0;
for (int i=1;iwhile (pnt<=cnt && (idx[pnt]>0?l[idx[pnt]]:r[-idx[pnt]])==i)
if (idx[pnt]>0)
t[e[idx[pnt]]]++,pnt++;
else
t[e[-idx[pnt]]]--,pnt++;
T[i][0]=t[0]; T[i][1]=t[1];
if (t[0]==m)
ans+=calc(sx[i],sx[i+1]-1,0);
if (t[1]==m)
ans+=calc(sx[i],sx[i+1]-1,1);
}
for (int i=1;iint it=upper_bound(sx+1,sx+icnt+1,b)-sx-1;
if (T[it][b&1]==m)
ans--;
}
printf("%lld\n",ans);
return 0;
}