新疆网赛G题(KMP+树状数组)

来源:互联网 发布:0基础php自学要多久 编辑:程序博客网 时间:2024/06/08 05:44


/#include<bits/stdc++.h>#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<bitset>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> P;#define fi first#define se second#define INF 0x3f3f3f3f#define clr(x,y) memset(x,y,sizeof x)#define PI acos(-1.0)#define ITER set<int>::iteratorconst int Mod = 1e9 + 7;const int maxn = 1e5 + 10;const int N = 2;int nexts[maxn],extand[maxn];char S[maxn],T[maxn];void Getnexts(const char *T) {    int len = strlen(T),a = 0;    nexts[0] = len;    while(a < len - 1 && T[a] == T[a + 1]) a++;    nexts[1] = a;    a = 1;    for(int k = 2; k < len; k ++) {        int p = a + nexts[a] - 1,L = nexts[k - a];        if( (k - 1) + L >= p) {            int j = (p - k + 1) > 0 ? (p - k + 1) : 0;            while(k + j < len && T[k + j] == T[j]) j++;            nexts[k] = j;            a = k;        } else            nexts[k] = L;    }}void GetExtand(const char *S,const char *T) {    Getnexts(T);    int slen = strlen(S),tlen = strlen(T),a = 0;    int MinLen = slen < tlen ? slen : tlen;    while(a < MinLen && S[a] == T[a]) a++;    extand[0] = a;    a = 0;    for(int k = 1; k < slen; k ++) {        int p = a + extand[a] - 1, L = nexts[k - a];        if( (k - 1) + L >= p) {            int j = (p - k + 1) > 0 ? (p - k + 1) : 0;            while(k + j < slen && j < tlen && S[k + j] == T[j]) j ++;            extand[k] = j;            a = k;        } else            extand[k] = L;    }}int tree[maxn << 2];inline int lowbit(int x){return x &(-x);}int get(int x){int ret = 0;for(int i = x; i > 0; i -= lowbit(i))ret += tree[i];return ret;}void update(int x,int val){for(int i = x; i < maxn; i += lowbit(i))tree[i] += val;}const ull D = 131;int main(){    int Tcase;scanf("%d",&Tcase);    while(Tcase --)    {        int n;scanf("%d",&n);        scanf("%s%s",S + 1,T + 1);int len1 = strlen(S + 1),len2 = strlen(T + 1);        GetExtand(S + 1,T + 1);clr(tree,0);        ull temp = 0,temp1 = 1;for(int i = 1; i <= len2; i ++)temp1 *= D;        for(int i = 1; i <= len2; i ++)temp = temp * D + T[i];        for(int i = 0; i < len1 - len2; i ++)        {            if(extand[i] == len2)            {                update(i + len2,1);            }        }        S[0] = 0;        while(n --)        {            char type[3];scanf("%s",type);            if(type[0] == 'Q')            {                int x,y;scanf("%d%d",&x,&y);                printf("%d\n",get(y) - get(x + len2 - 2));            }            else            {                int x;char c[2];scanf("%d%s",&x,c);if(c[0] == S[x])continue;                int l = max(x - len2 + 1,1),r = min(x + len2 - 1,len1);                for(int j = l; j <= r - len2 + 1; j ++)                {                    int t = get(j + len2 - 1) - get(j + len2 - 2);                    if(t)update(j + len2 - 1,-t);                }                S[x] = c[0];ull K = 0;int t = 1;                for(int j = l; t <= len2 && j <= r; j ++,t ++)K = K * D + S[j];//                cout << K << " >> " << temp << " " << t  << endl;                if(t > len2 && K == temp){update(l + len2 - 1,1);}//cout << l + len2 - 1 << endl;                if(t > len2)                for(int j = l + len2;j <= r; j ++)                {                    K = K * D - S[j - len2] * temp1 + S[j];                    if(K == temp)                    {//                        cout << j << endl;                        update(j,1);                    }                }            }        }        puts("");    }    return 0;}