http://codeforces.com/contest/828/problem/E
题意:给你一个字符串s
m次操作 op==1 改变s[pos]位置的字符
op==2 将字符串e复制无限次 求从l开始s[l] == e[0] ,s[l+1] == e[1] ...... s[r] == e[r-l]成立的有多少个
思路: 在DT大神的指导下 知道了将s进行分组
由于e只有<=10 且字符只有四种
所以可以枚举 字母 周期(e的长度) 首位置(l)
具体科一看代码
ACcode:
#include<bits/stdc++.h>
using namespace std;
struct Bittree
{
int c[100010];
void add(int x, int val)
{
while(x < 100005)
{
c[x] += val;
x += (x & -x);
}
}
int sum(int x)
{
int ret = 0;
while(x > 0)
{
ret += c[x];
x -= (x & -x);
}
return ret;
}
} tree[4][11][11];///字母 周期 首位置分组
char s[100010];
int id(char c)
{
if(c == 'A') return 0;
if(c == 'T') return 1;
if(c == 'G') return 2;
if(c == 'C') return 3;
}
int main()
{
scanf("%s", s + 1);
int n = strlen(s + 1);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= 10; j++)
tree[id(s[i])][j][i % j].add(i, 1);
int m;scanf("%d", &m);
for(int i = 1; i <= m; i++)
{
int op;scanf("%d", &op);
if(op == 1)
{
int pos;char t[20];
scanf("%d%s", &pos, t + 1);
for(int j = 1; j <= 10; j++)
{
tree[id(s[pos])][j][pos % j].add(pos, -1);
tree[id(t[1]) ][j][pos % j].add(pos, 1);
}
s[pos]=t[1];
}
else
{
int l, r;scanf("%d%d", &l, &r);
char t[20];scanf("%s", t + 1);
int len = strlen(t + 1);
int ans = 0;
for(int j = 1; j <= len; j++)
{
ans += tree[id(t[j])][len][(l + j - 1) % len].sum(r) - tree[id(t[j])][len][(l + j - 1) % len].sum(l - 1);
}
printf("%d\n", ans);
}
}
return 0;
}