【NOIP模拟】玛雅文字

题面

解读玛雅文字向来不简单,因为单词中的字母顺序可以是任意排列的。今天,科研团队找到了你来解决一个简化过的问题——在给定的一段玛雅文字 S 中,求出给定的单词 T 出现了几次,并保证 S 和 T 均由大小写字母构成。

1≤|T|≤ 3000,|T|≤|S|≤ 3,000,000

分析

和顺序无关代表仅和字母以及字母数量有关

直接维护S的每个长度为T区间的每个字母的个数,因为区间每次向右移动的时候,只会改变一头一尾两个字母的数量

于是可以线性维护

代码

#include<bits/stdc++.h>
using namespace std;
#define N 3030
#define M 3000030
int n,m,ans;
char t[M],s[N];
int o[70],vis[70],now[70];
inline int f(char c)
{
    if(c-'A'>25)return c-'A'-6;
    return c-'A';
}

int main()
{
    scanf("%d%d",&n,&m);scanf("%s%s",s+1,t+1);
    for(int i=1;i<=n;i++)o[f(s[i])]++,now[f(t[i])]++;
    for(int i=n+1;i<=m+1;i++)
    {
        ans++;
        for(int j=0;j<=51;j++)
            if(now[j]!=o[j])
                {ans--;break;}
        if(i!=m+1)now[f(t[i])]++,now[f(t[i-n])]--;
    }
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/NSD-email0820/p/9889058.html