zoukankan      html  css  js  c++  java
  • HDU

    题意:给你多个数字串,求本质不同的子串和(去掉前导零)
    题解:建广义sam,刚开始一直想的是用l来计算,发现前导零对l的影响根本消不掉,所以不会做= =,原来应该是直接用一个新的数组表示到当前有多少个子串就好了

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 2012
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    //#define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("c.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    template<typename T>
    inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>
    inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    
    const double eps=1e-8;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=100000+10,maxn=100000+10,inf=0x3f3f3f3f;
    
    char s[N];
    struct SAM{
        int last,cnt;
        int ch[N<<1][10],fa[N<<1],l[N<<1],c[N<<1];
        int a[N<<1],num[N<<1],sum[N<<1];
        void init()
        {
            cnt=1;
        }
        void ins(int x)
        {
            if(ch[last][x])
            {
                int p=last,q=ch[last][x];
                if(l[q]==l[p]+1)last=q;
                else
                {
                    int nq=++cnt;l[nq]=l[p]+1;
                    memcpy(ch[nq],ch[q],sizeof ch[q]);
                    fa[nq]=fa[q];fa[q]=last=nq;
                    for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
                }
                return ;
            }
            int p=last,np=++cnt;last=np;l[np]=l[p]+1;
            for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np;
            if(!p)fa[np]=1;
            else
            {
                int q=ch[p][x];
                if(l[q]==l[p]+1)fa[np]=q;
                else
                {
                    int nq=++cnt;l[nq]=l[p]+1;
                    memcpy(ch[nq],ch[q],sizeof ch[q]);
                    fa[nq]=fa[q];fa[q]=fa[np]=nq;
                    for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
                }
            }
        }
        void topo()
        {
            for(int i=1;i<=cnt;i++)c[l[i]]++;
            for(int i=1;i<=cnt;i++)c[i]+=c[i-1];
            for(int i=1;i<=cnt;i++)a[c[l[i]]--]=i;
        }
        void build()
        {
            last=1;
            int len=strlen(s+1);
            for(int i=1;i<=len;i++)ins(s[i]-'0');
        }
        void cal()
        {
            topo();
            num[1]=1;
            for(int i=1;i<=cnt;i++)
            {
                int p=a[i];
                for(int j=0;j<10;j++)
                    if(ch[p][j])
                    {
                        if(i==1&&j==0)continue;
                        num[ch[p][j]]+=num[p];
                        sum[ch[p][j]]=(sum[ch[p][j]]+(sum[p]*10+num[p]*j)%mod)%mod;
                    }
            }
            int ans=0;
            for(int i=1;i<=cnt;i++)
                ans=(ans+sum[i])%mod;
            printf("%d
    ",ans);
            for(int i=0;i<=cnt;i++)
            {
                for(int j=0;j<10;j++)ch[i][j]=0;
                sum[i]=fa[i]=num[i]=a[i]=c[i]=l[i]=0;
            }
        }
    }sam;
    int main()
    {
    //    fin;
        int n;
        while(~scanf("%d",&n))
        {
            sam.init();
            for(int i=0;i<n;i++)
            {
                scanf("%s",s+1);
                sam.build();
            }
            sam.cal();
        }
        return 0;
    }
    /********************
    3
    12
    012
    0012
    ********************/
    
  • 相关阅读:
    jquery 序列化form表单
    nginx for windows 安装
    nodejs idea 创建项目 (一)
    spring 配置 shiro rememberMe
    idea 2018 解决 双击shift 弹出 search everywhere 搜索框的方法
    redis 在windows 集群
    spring IOC控制反转和DI依赖注入
    redis 的安装
    shiro 通过jdbc连接数据库
    handlebars的用法
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9809839.html
Copyright © 2011-2022 走看看