zoukankan      html  css  js  c++  java
  • UVALive

    题目链接:

    http://acm.hust.edu.cn/vjudge/problem/82135

    Circle of digits

    Time Limit: 3000MS

    题意

    把循环串分割成k块,让值最大的那块值最小。

    题解

    用后缀数组给循环串排序。然后二分答案(长度肯定为(n+k-1)/k)。二分判断时,枚举分割的起点,然后贪心每次尽可能取长度为(n+k-1)/k。

    代码

    #include<map>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    //#define lson (o<<1)
    //#define rson ((o<<1)|1)
    //#define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) ;//cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    
    const int maxn = 1e5 + 10;
    
    int n,k;
    
    struct SuffixArray{
        char s[maxn];
        int sa[maxn],t[maxn],t2[maxn],c[maxn];
        int n,m;
        void init(int n,int m){
            this->n=n;
            this->m=m;
        }
        void build_sa(){
            int i,*x=t,*y=t2;
            for(i=0;i<m;i++) c[i]=0;
            for(i=0;i<n;i++) c[x[i]=s[i]]++;
            for(i=1;i<m;i++) c[i]+=c[i-1];
            for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
            for(int k=1;k<=n;k<<=1){
                int p=0;
                for(i=0;i<n;i++) y[p++]=(sa[i]-k+n)%n;
                
                for(i=0;i<m;i++) c[i]=0;
                for(i=0;i<n;i++) c[x[y[i]]]++;
                for(i=1;i<m;i++) c[i]+=c[i-1];
                for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
                
                swap(x,y);
                p=1; x[sa[0]]=0;
                for(i=1;i<n;i++){
                    x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
                }
                if(p>=n) break;
                m=p;
            }
        }
        int cmp(int p1,int p2){
        	int ret=0;
        	int len=(n+k-1)/k;
        	rep(i,0,len){
        		if(s[(p1+i)%n]<s[(p2+i)%n]) return -1;
        		if(s[(p1+i)%n]>s[(p2+i)%n]) return 1;
    		}
    		return 0;
    	}
        bool check(int x){
        	int len=(n+k-1)/k;
        	bug(sa[x]);
        	bug(x);
        	rep(i,0,len){
        		int ed=i;
        		rep(j,0,k){
        			if(cmp(ed%n,sa[x])<=0){
        				bug(ed%n);
        				ed+=len;
    				}
    				else ed+=len-1;
    			}
    			if(ed-i>=n) return true;
    		}
        	return false;
    	}
    	void solve(){
    		build_sa();
    		int l=0,r=n-1;
    		while(l<r){
    			int mid=l+(r-l)/2;
    			if(check(mid)) r=mid;
    			else l=mid+1;
    		}
    		int len=(n+k-1)/k;
    		for(int i=sa[r];i<len+sa[r];i++) printf("%c",s[i%n]);
    		printf("
    ");
    	}
    }mysa;
    
    int main() {
        while(scanf("%d%d",&n,&k)==2&&n){
        	mysa.init(n,256);
        	scanf("%s",mysa.s);
        	mysa.solve();
    	}
        return 0;
    }
  • 相关阅读:
    VSCode显示多个Tab窗口
    react + antd实现动态菜单
    vue 全局插件封装--提示toast
    ElementUI之el-scrollbar+el-select组合
    vue 滚动条组件对比
    【智能车】NXP_MIMXRT1064库函数
    【模电学习】二极管的特性与参数
    【模电学习】半导体——N与P(2)
    【协议】IIC通信
    【模电学习】半导体——N与P(1)
  • 原文地址:https://www.cnblogs.com/fenice/p/5767091.html
Copyright © 2011-2022 走看看