zoukankan      html  css  js  c++  java
  • bzoj4486: [Jsoi2015]串分割

    肉丝哥哥钦定好题 话说我的blog现在为什么到处都是肉丝哥哥

    先来想一个弱化版,假如能够n整除K怎么做?

    把每个数字看成一个字符串,按字典序排名,这个可以后缀数组解决,然后暴力枚举每种情况,O(1)判两个长度为n/K的数字大小即可

    然后不能整除一定是有n-n/K*K个长度为n/K+1的数字

    先二分答案排名,枚举起始位置,考虑一个贪心的做法,假如当前能够放一个长度为n/K+1的就立刻放,这样能够保证最优

    why?放n/K+1和n/K的区别相当于多往前走了1步,但是多用了一组n/K+1,假如走n/K在未来某一决策能够走n/K+1,那么当前走n/K+1只需付出少用一组就可以拉回同一起跑线。其实也就是具有决策包容性

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int _=1e2;
    const int maxn=2*2e5+_;
    int n,K,U;char ss[maxn];
    
    int sa[maxn],Rank[maxn];
    namespace SA
    {
        int Rsort[maxn],tt[maxn];
        void getsa(int n,int m)
        {
            for(int i=1;i<=n;i++)Rank[i]=ss[i]-'0';
            
            memset(Rsort,0,sizeof(Rsort));
            for(int i=1;i<=n;i++)Rsort[Rank[i]]++;
            for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1];
            for(int i=n;i>=1;i--)sa[Rsort[Rank[i]]--]=i;
            
            int ln=1,p=0;
            while(p<n)
            {
                int k=0;for(int i=n-ln+1;i<=n;i++)tt[++k]=i;
                for(int i=1;i<=n;i++)
                    if(sa[i]-ln>0)tt[++k]=sa[i]-ln;
                    
                memset(Rsort,0,sizeof(Rsort));
                for(int i=1;i<=n;i++)Rsort[Rank[tt[i]]]++;
                for(int i=1;i<=m;i++)Rsort[i]+=Rsort[i-1];
                for(int i=n;i>=1;i--)sa[Rsort[Rank[tt[i]]]--]=tt[i];
                
                for(int i=1;i<=n;i++)tt[i]=Rank[i];
                
                p=1;Rank[sa[1]]=1;
                for(int i=2;i<=n;i++)
                {
                    if(tt[sa[i]]!=tt[sa[i-1]]||tt[sa[i]+ln]!=tt[sa[i-1]+ln])p++;
                    Rank[sa[i]]=p;
                }
                
                m=p;ln*=2;
            }
        }
        void GetTrueRank(int n)
        {
            int p=0;
            for(int i=1;i<=2*n-1;i++)
                if(sa[i]<=n)Rank[sa[i]]=Rank[sa[i]+n]=++p;
            
            for(int i=1;i<=n;i++)sa[Rank[i]]=i;
        }    
        void main(int n){getsa(2*n-1,15);GetTrueRank(n);}
    }
    
    namespace PRINT
    {
        void main(int ans,int len)
        {
            int st=sa[ans];
            for(int i=1;i<=len;i++)putchar(ss[i+st-1]);
            puts("");
        }
    }
    namespace SOL1
    {
        void main()
        {
            int ans=(1<<30);
            for(int i=1;i<=U;i++)
            {
                int num=0,tt=0;
                for(int j=1;j<=K;j++)
                    num=max(num,Rank[i+tt]),tt+=U;
                ans=min(ans,num);
            }
            PRINT::main(ans,U);
        }
    }
    namespace SOL2
    {
        int calc(int em)
        {
            int mmax=0;
            for(int i=1;i<=U+1;i++)
            {
                int p=i,num=0;
                for(int j=1;j<=K;j++)
                {
                    if(Rank[p]<=em)p+=U+1,num++;
                    else p+=U;
                    if(p>=i+n-1)break;
                }
                mmax=max(mmax,num);
            }
            return mmax;
        }
        void main()
        {
            int res=n-U*K;
            int el=1,er=n,em,ans;
            while(el<=er)
            {
                em=(el+er)/2;
                if(calc(em)>=res)
                {
                    er=em-1;
                    ans=em;
                }
                else el=em+1;
            }
            PRINT::main(ans,U+1);
        }
    }
    
    int main()
    {
        scanf("%d%d%s",&n,&K,ss+1); U=n/K;
        for(int i=1;i<n;i++)ss[i+n]=ss[i];
        SA::main(n);
        
        if(n%K==0)SOL1::main();
        else SOL2::main();
        
        return 0;
    }
  • 相关阅读:
    将数据导入PostGIS
    图层管理
    CentIOS PHP 扩展库
    js 笔记 数组(对象)
    JSP 中的 Request 和 Response 对象
    ubuntu 安装 LAMP
    html 学习笔记
    Struts Ajax Json
    Servlet 笔记
    PHP+MYSQL 出现乱码的解决方法
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10622132.html
Copyright © 2011-2022 走看看