CF827C 题解
题目大意:
给一个长度只包含
- 修改某个位置的字母。
- 给定一个字符串
s(|s|\le 10) ,生成一个重复的新串sssss \cdots 。询问[L,R] 中有几个字母跟新字符串对应。
Sol
设母串为
注意到每次询问中的字符串
假设每次询问的区间都是
我们只对
对于
分析对于每种可能的
- 对于每个
i 。 - 对于每个可能的
s_i 。
我们都建立一个长度为
且其中
总共需预处理
再分析对于一般询问
只需要对
对于
然后在
核心代码
#define N 100010
int n,m, sum[4][11][11][N],has[128];
char t[N],s[20];
int lowbit(int x){
return x&(-x);
}
void change(int c,int p,int v){
for(int x=p;x<=n;x+=lowbit(x)){
for(int j=1;j<=10;j++){
sum[c][j][p%j][x]+=v;
}
}
}
int query(int c,int len,int p,int x){
int ret=0;
while(x){
ret+=sum[c][1en][p][x];
x-=lowbit(x);
}
return ret;
}
int main() {
has['A']=0,has['T']=1,has['C']=2,has['G']=3;
scanf("%s" ,t+1);
n=strlen(t+1);
for(int i=1;i<=n;i++)
change(has[t[i]],i,1);
int op,1,r,x;
char c;
m=read();
while(m--){
op=read();
if(op==1){
scanf("%d %c",&x,&c);
change(has[t[x]],x,-1);
change(has[c],x,1);
t[x]=c;
}else{
scanf("%d %d %s",&1,&r,&s);
int len=strlen(s), ans=0;
for(int i=0;i<len;i++){
ans+=query(has[s[i]],len, (i+1)%len,r);
query(has[s[i]],len,(i+l)%len,1-1);
printf( "%d\n",ans);
}
}
}
return 0;
}