G: Query on a string

来源:互联网 发布:app数据分析网站 编辑:程序博客网 时间:2024/04/26 19:08

G: Query on a string
这里写图片描述
这里写图片描述

给定字符串S和T,N次操作,包括修改 S 一个字符或者查询 S 中 [l,r],T 出现的次数
用树状数组就好了,因为 |T|<=10,每次用个数组记录,如果a[i]=1,代表 T 在 S 中出现而且结尾坐标为i,那么每次查询就相当于询问 [l+len_t-1, r] 中有多少个1,用树状数组维护就好了

#include <bits/stdc++.h>using namespace std;const int maxn = 100010;int a[maxn], f[maxn], n, m, x, y, l, r;char s[maxn], t[100], c;int len_s, len_t;void insert(int x, int y) {    while (x < maxn) {        f[x] += y;        x = x+(x & (-x));    }}int find(int x) {    int v = 0;    while (x > 0) {        v += f[x];        x = x-(x & (-x));    }    return v;}void init() {    memset(a, 0, sizeof(a));    memset(f, 0, sizeof(f));    scanf("%d", &n);    scanf("%s", s+1);    scanf("%s", t+1);    len_s = strlen(s+1);    len_t = strlen(t+1);    for (int i = 1; i+len_t-1 <= len_s; i++) {        bool flag = true;        for (int j = 1; j <= len_t; j++) if (s[i+j-1] != t[j]) flag = false;        if (flag) {            a[i+len_t-1]++;            insert(i+len_t-1, 1);        }    }}void work() {    for (int i = 1; i <= n; i++) {        scanf("%c", &c);        scanf("%c", &c);        if (c == 'Q') {            scanf("%d %d", &l, &r);            printf("%d\n", max(0, find(r)-find(l+len_t-1-1)));        } else {            scanf("%d %c", &x, &c);            s[x] = c;            for (int i = max(1, x-len_t+1); i <= x; i++) {                bool flag = true;                for (int j = 1; j <= len_t; j++) if (s[i+j-1] != t[j]) flag = false;                if (flag && !a[i+len_t-1]) {                    a[i+len_t-1]++;                    insert(i+len_t-1, 1);                } else if (!flag && a[i+len_t-1]) {                    a[i+len_t-1]--;                    insert(i+len_t-1, -1);                }            }        }    }}int main() {    freopen("input.txt","r",stdin);    int T;    scanf("%d", &T);    while (T--) {        init();        work();        printf("\n");    }}
阅读全文
1 0
原创粉丝点击