Gym - 101532D Counting Test 前缀和统计字符串

题意:给你一个1e4长的字符串S,有1e5个询问,每个询问形如 l r c ,其中l,r为左右边界,c为所询问的字符。注意,l,r,可以大于串S的长度,这种情况下认为S自身重复无数次(S+S+S···)。l,r范围1e9。

题解:预处理前缀和(多处理一下),先打表dp[256][10005],dp['a'][x]代表1~x中'a'出现几次,有dp[s[i-1]][i]=dp[s[i-1]][i-1]。然后输出区间时直接输出sum(r)-sum(l),其中sum(x)为计算1~x区间某字符串出现的次数。

坑点:cin,cout用一个就会T。不用前缀和会wa...可能打错了什么。还有这个表达式a[c][n] *( x / n)不遵守交换律

ac代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<string.h>
#include<stdio.h>
using namespace std;
const int maxn = 1e4 + 5;
int n, q;
int a[256][maxn];
int sum(int x,char c) {
    int ans=0;
    ans = a[c][n] *( x / n);
    x %= n;
    ans += a[c][x];
    return ans;
};
int main() {
    int t;
    cin >> t;
    while (t--) {
        memset(a, 0, sizeof(a));
        
        cin >> n >> q;
        string s;
        cin >> s;
        a[s[0]][1]++;
        for (int i = 2; i <= n; i++) {
            for (int j = 'a'; j <= 'z'; j++) {
                a[j][i] = a[j][i - 1];
            }
            a[s[i - 1]][i] = a[s[i - 1]][i - 1] + 1;

        }
        for (int i = 1; i <= q; i++) {
            int l, r;
            scanf("%d%d", &l, &r);
            int x = l / n + 1, y = r / n;
            int z = y - x;
            //l %= n; r %= n;
            char c[5];
            scanf("%s", c);
            printf("%d\n",sum(r,c[0]) - sum(l-1,c[0]));
            

        }
    }

 

posted @ 2018-03-06 13:15  SuuTTT  阅读(382)  评论(0编辑  收藏  举报