• CCC比赛T3


    参加了CCC

    我好菜啊

    做对的就几道水题

    T3的题目大意是给一个字串,然后再给一个母串,看字串有几种排列方式在母串中出现过

    (只包含小写字母)

    举个例子

    ab的排列在aba中出现过2种

    ab和ba

    数据范围是10^5(好像

    首先是判断排列,按照全排列来判断肯定不行,所以选择使用一个数组,记录每个字母出现的次数

    在母串判断的时候滑动一下就可以判断是否是字串的一种排列方式,因为只要每个字母的数量都一样,就说明是一种排列

    然后如何避免排列重复呢,直接用一个hash就可以,因为这道题的数据还挺强的,我开了三个hash才过掉(也可能是因为我脸黑

    反正这道题是水题,我就不多说了(找机会把后面两道题弄懂

    上代码吧:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #define mod1 12582917
    #define mod2 6291469
    #define mod3 25165843
    #define base 131
    #define ULL unsigned long long
    using namespace std;
    inline long long rd(){
        long long x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    inline void write(long long x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
        return ;
    }
    char ch1[1000006],ch2[1000006];
    int cnt[1006];
    int num[1006];
    ULL ha[1000006];
    ULL poww[1000006];
    int n,m;
    bool book1[13000006];
    bool book2[13000006];
    bool book3[30000006];
    int ans=0;
    inline ULL geth(int l,int r){
        return ha[r]-(ha[l-1]*poww[r-l+1]);
    }
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        poww[0]=1;
        for(int i=1;i<=1000006;i++) poww[i]=(poww[i-1]*base);
        cin>>ch1+1;
        cin>>ch2+1;
        n=strlen(ch1+1);
        m=strlen(ch2+1);
        for(int i=1;i<=m;i++){
            ha[i]=((ha[i-1]*base)+(ULL)(ch2[i]-'a'+1));
        }
        for(int i=1;i<=n;i++){
            cnt[ch1[i]-'a'+1]++;
        }
        for(int i=1;i<=n;i++){
            num[ch2[i]-'a'+1]++;
        }
        for(int i=n;i<=m;i++){
            int f=0;
            for(int j=1;j<=26;j++){
                if(cnt[j]!=num[j]){
                    f=1;
                    break;
                }
            }
            num[ch2[i-n+1]-'a'+1]--;
            num[ch2[i+1]-'a'+1]++;
            if(f) continue;
            ULL v1=geth(i-n+1,i);
            ULL v2=v1,v3=v1;
            v1%=mod1;
            v2%=mod2;
            v3%=mod3;
            if(!book1[v1]||!book2[v2]||!book3[v3]){
                book1[v1]=book2[v2]=book3[v3]=1;
                ans++;
            }
        }
        write(ans);
        return 0;
    }
  • 相关阅读:
    [国家集训队]数颜色 / 维护队列
    [SP3267]DQUERY
    扩展欧几里得算法详解(exgcd)
    [CTSC2018]混合果汁
    极角排序那些事
    向量的点乘与叉乘学习笔记
    [APIO2014]序列分割
    CF1148D-Dirty Deeds Done Dirt Cheap
    CF176E Archaeology(set用法提示)
    【网络流24题】最长不下降子序列问题
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/12431637.html
Copyright © 2020-2023  润新知