codeforces1311C. Perform the Combo

题目连接: 老师永远不知道在上网课的学生都在干嘛

给出一个字符串,再给出m个子串,求子串和原串个字母出现的次数


这题不是很难,最难的是好久不写把输出函数给忘了
最朴素的算法就是把每个子串都走一遍累加,但是时间和空间复杂都太高,所以就想,能不能统计每个位置出现的次数。

每个子串结束之前必然要计数一次,所以记录每个子串结束的位置,倒序遍历原串,若当前位置有子串结束,那么之前的位置都要计数一次,所以出现次数+1.
要注意的是这里不只有子串,还有原串,因此原串的最后一个位置初始值为1

#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

template<class T> void _deb(const char *name,T val){
    cout<<name<<val<<endl;
}

const int maxn=2e5+5;

int T;
int n,m;
char store[maxn];  %原串
int mistake[maxn];  %错误位置
int times[maxn];  %每个位置的出现次数
int statistics[26];  %每个字母出现的总次数
int main(){
    scanf("%d",&T);
    while(T--){
        mem(statistics,0);
        mem(times,0);

        scanf("%d%d",&n,&m);
        scanf("%s", store+1);
        rep(i,0,m){
            scanf("%d",&mistake[i]);
        }

        sort(mistake,mistake+m);
        times[n]=1;
        drep(i,m-1,0){
            times[mistake[i]]+=1;
        }
        drep(i,n,1){
            int pos = store[i]-'a';
            times[i] += times[i+1];
            statistics[pos] += times[i];
        }

        rep(i,0,26){
            printf("%d ",statistics[i]);
        }
        printf("\n");
    }
    re 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值