zoukankan      html  css  js  c++  java
  • Contest 20140928 密碼破譯 字符串hash

      題意:詢問字符串指定區間循環節個數。

      解法:有循環節長度a的字符串s[x,y]的性質:s[x,y-a]==s[x+a,y]由此寫一個雙hash就行了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    #define MAXN 1100000
    #define MAXV MAXN*2
    #define MAXE MAXV*2
    #define INF 0x3f3f3f3f
    #define INFL 0x3f3f3f3f3f3f3f3fLL
    #define PROB "password"
    #define _a 29
    #define _b 131
    #define mod 1000000007
    typedef unsigned long long qword;
    inline int nextInt()
    {
            char ch;
            int x=0;
            bool flag=false;
            do
                    ch=getchar(),flag=(ch=='-')?true:flag;
            while(ch<'0'||ch>'9');
            do x=x*10+ch-'0';
            while (ch=getchar(),ch<='9' && ch>='0');
            return x*(flag?-1:1);
    }
    
    int n,m;
    char str[MAXN];
    pair<qword,qword> hs[MAXN];
    bool pflag[MAXN];
    int prime[MAXN],topp=-1;
    qword pow_a[MAXN];
    qword pow_b[MAXN];
    void init()
    {
            int i,j;
            for (i=2;i*i<MAXN;i++)
            {
                    if (!pflag[i])
                            prime[++topp]=i;
                    for (j=0;j<=topp && i*prime[j]<MAXN;j++)
                    {
                            pflag[i*prime[j]]=true;
                            if (i%prime[j]==0)break;
                    }
            }
            pow_a[0]=1;
            pow_b[0]=1;
            for (i=1;i<MAXN;i++)
                    pow_a[i]=pow_a[i-1]*_a%mod,
                            pow_b[i]=pow_b[i-1]*_b;
    }
    pair<qword,qword> hash(int x,int y)
    {
            pair<qword,qword> ret;
            ret.first=((hs[x].first+mod-hs[y+1].first*pow_a[(y+1)-x]%mod)%mod+mod)%mod;/*Attention*/
            ret.second=hs[x].second-hs[y+1].second*pow_b[(y+1)-x];
            return ret;
    }
    int check(int x,int y)
    {
            int ret=1;
            int len=(y-x+1);
            int lo=len;
            int a,i;
            for (i=0;i<=topp && prime[i]*prime[i]<=len;i++)
            {
                    if (len%prime[i]==0)
                    {
                            a=1;
                            while (len%prime[i]==0)
                            {
                                    len/=prime[i];
                                    a*=prime[i];
                                    if (hash(x,y-lo/a)==hash(x+lo/a,y))
                                    {
                                            ret*=prime[i];
                                    }
                            }
                    }
            }
            if (len>1)
            {
                    a=len;
                    if (hash(x,y-lo/a)==hash(x+lo/a,y))
                    {
                            ret*=a;
                    }
            }
            return ret;
    }
    
    int main()
    {
            freopen(PROB".in","r",stdin);
            //freopen(PROB".out","w",stdout);
            int i,j,k;
            int x,y,z;
            int ans;
            init();
            scanf("%d
    ",&n);
            fgets(str,sizeof(str),stdin);
            hs[n]=make_pair(1,1);
            for (i=n-1;i>=0;i--)
            {
                    hs[i].first=hs[i+1].first*_a%mod+str[i]-'a'+1;
                    hs[i].second=hs[i+1].second*_b+str[i]-'a'+1;
            }
    //        pr3=hash(5,5);
            scanf("%d",&m);
            for (i=0;i<m;i++)
            {
                    scanf("%d%d",&x,&y);
                    x--;y--;
                    printf("%d
    ",(y-x+1)/check(x,y));
            }
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    Python下用Tkinter进行GUI编程
    6月3日——回首一个半月
    Consistent Hashing算法
    学生终究要面对社会
    MySQL的锁(1)
    Memcached笔记之分布式算法(idv2.com)
    4月21日总结
    2012.3.29小结
    C#调用c++创建的dll
    以post方式发送文档到端口
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4000388.html
Copyright © 2011-2022 走看看