zoukankan      html  css  js  c++  java
  • BZOJ 2081: [Poi2010]Beads

    Description

    问把n截成每个长度后不同子串个数.

    Sol

    调和极数+Hash.

    首先这是一个式子 (nsum_{i=1}^n frac {1}{i}) .

    这东西就是调和极数再乘上 (n) ,他趋近于(nlnn)

    正反哈希一下.

    Code

    /**************************************************************
        Problem: 2081
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:6420 ms
        Memory:58552 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    #define debug(a) cout<<#a<<"="<<a<<" "
     
    typedef long long LL;
    const int N = 2e5+50;
    const LL bs = 666671;
    const LL p = 5831801;
     
     
    LL n,ans,ans1;
    LL a[N],b[N],rb[N],v[2][N];
    vector< int > as;
     
    struct HashTable {
        int h[p],nxt[p],cnt;
        int q[N],t;
        LL v[N];
         
        void insert(LL x,LL val) {
            v[++cnt]=val,nxt[cnt]=h[x],h[x]=cnt;
            q[++t]=x;
        }
        LL find(LL x,LL val) {
            for(int i=h[x];i;i=nxt[i]) if(v[i]==val) return 1;
            return -1;
        }
        void clear() {
            for(int i=1;i<=t;i++) h[q[i]]=0;
            cnt=0,t=0;
        }
    }hh;
     
    inline LL in(LL x=0,char ch=getchar()) { while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
    inline LL Pow(LL a,LL b,LL r=1) { for(;b;b>>=1,a=a*a%p) if(b&1) r=r*a%p;return r; }
    LL GetVal(int kd,LL l,LL r) {
        if(!kd) return (v[kd][r]-v[kd][l-1]+p)%p*rb[l-1]%p;
        else return (v[kd][l]-v[kd][r+1]+p)%p*rb[n-r]%p;
    }
    int main() {
        n=in();
        for(int i=1;i<=n;i++) a[i]=in();
        b[0]=b[1]=1;for(int i=2;i<=n;i++) b[i]=b[i-1]*bs%p;
        rb[0]=1,rb[1]=Pow(bs,p-2);for(int i=2;i<=n;i++) rb[i]=rb[i-1]*rb[1]%p;
         
        for(int i=1;i<=n;i++) v[0][i]=(v[0][i-1]+a[i]*b[i]%p)%p;
        for(int i=n;i>=1;i--) v[1][i]=(v[1][i+1]+a[i]*b[n-i+1]%p)%p;
         
        for(int i=1;i<=n;i++) {
            int r=0;
            hh.clear();
    //      cout<<i<<":"<<endl;
            for(int j=1;j+i-1<=n;j+=i) {
                LL vv1=GetVal(0,j,j+i-1),vv2=GetVal(1,j,j+i-1);
    //          debug(vv1),debug(vv2)<<endl;
                 
                if(vv1>vv2) swap(vv1,vv2);
                if(hh.find(vv1,vv2)==-1) hh.insert(vv1,vv2),r++;
            }
    //      debug(r)<<endl;
    //      cout<<"---------------------"<<endl;
            if(r>ans) as.clear(),as.push_back(i),ans=r;
            else if(r==ans) as.push_back(i);
        }
        ans1=as.size();
        printf("%lld %lld
    ",ans,ans1);
        for(int i=0;i<ans1;i++) printf("%d%c",as[i]," 
    "[i==ans1-1]);
        return 0;
    }
     
    /*
    21
    1 1 1 2 2 2 3 3 3 1 2 3 3 1 2 2 1 3 3 2 1
    */
    
  • 相关阅读:
    udhcp源码详解(四) 之租赁IP的管理
    udhcp源码详解(四) 之租赁IP的管理
    udhcp源码详解(三) 下 之配置信息的读取
    udhcp源码详解(三)上 之配置信息的读取
    udhcp源码详解(二)--转
    udhcp详解源码(序)
    udhcp源码详解(一)之文件组织结构(dhcp server) --转
    UNIX网络编程学习(9)--getsockname和getpeername的用法及实例(转)
    php 函数
    git-命令
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6216100.html
Copyright © 2011-2022 走看看