zoukankan      html  css  js  c++  java
  • [SDOI2008]Sandy的卡片

    题目大意:

    给你n个串(s_1sim s_n),要你在每个串中找一个长度为k的子串,满足任意(1leqslant i<k),有(s_1[i+1]-s_1[i]=s_2[i+1]-s_2[i]=dots=s_n[i+1]-s_n[i])。问满足条件的k最大是多少。

    解题思路:

    相邻两个数差相等,我们先将原串进行差分。

    然后首尾相连求后缀数组(中间用分隔符隔开)。

    二分答案。对于答案t,考虑height数组中所有连续的,且大于等于t的子区间,若包含1~n所有串,则答案可行。

    由于进行了差分,最后答案+1即可。

    C++ Code:

    #include<bits/stdc++.h>
    const int NN=1200005;
    inline int readint(){
        int c=getchar(),d=0,f=0;
        for(;!isdigit(c);c=getchar())f=c=='-';
        for(;isdigit(c);c=getchar())
        d=(d<<3)+(d<<1)+(c^'0');
        return f?-d:d;
    }
    int N,s[NN],n=0,a[1005],fg=30005,t1[NN],t2[NN],c[NN],rk[NN],height[NN],belong[NN],sa[NN];
    bool vis[1005];
    inline void sa_sort(){
        int*x=t1,*y=t2,m=60000;
        memset(c,0,sizeof c);
        for(int i=1;i<=n;++i)++c[x[i]=s[i]];
        for(int i=1;i<=m;++i)c[i]+=c[i-1];
        for(int i=n;i;--i)sa[c[x[i]]--]=i;
        for(int k=1;k<=n;k<<=1){
            int p=0;
            for(int i=n-k+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k;
            for(int i=0;i<=m;++i)c[i]=0;
            for(int i=1;i<=n;++i)++c[x[y[i]]];
            for(int i=1;i<=m;++i)c[i]+=c[i-1];
            for(int i=n;i;--i)sa[c[x[y[i]]]--]=y[i];
            int*tmp=x;x=y,y=tmp;
            x[sa[p=1]]=1;
            for(int i=2;i<=n;++i)
            x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p;
            if(p==n)break;
            m=p;
        }
    }
    inline void get_height(){
        for(int i=1;i<=n;++i)rk[sa[i]]=i;
        for(int i=1,k=0;i<=n;++i)
        if(rk[i]!=1){
            if(k)--k;
            int j=sa[rk[i]-1];
            while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k])++k;
            height[rk[i]]=k;
        }
    }
    inline bool check(int k){
        memset(vis,0,sizeof vis);
        int ok=1;
        vis[belong[sa[1]]]=1;
        for(int i=2;i<=n;++i){
            if(height[i]>=k){
                if(!vis[belong[sa[i]]]){
                    vis[belong[sa[i]]]=1;
                    if(++ok>=N)return 1;
                }
            }else{
                int j;
                for(j=i-1;j&&height[j]>=k;--j)
                vis[belong[sa[j]]]=0;
                vis[belong[sa[j]]]=0;
                vis[belong[sa[i]]]=1;
                ok=1;
            }
            if(!belong[sa[i]])break;
        }
        return 0;
    }
    int main(){
        N=readint();
        for(int i=1;i<=N;++i){
            int nn=readint();
            for(int j=0;j<nn;++j)a[j]=readint();
            for(int j=nn-1;j;--j)a[j]-=a[j-1];
            for(int j=1;j<nn;++j)s[++n]=a[j]+10001,belong[n]=i;
            s[++n]=fg++;
        }
        sa_sort();
        get_height();
        int l=1,r=1001,ans=0;
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid))l=(ans=mid)+1;else
            r=mid-1;
        }
        printf("%d
    ",ans+1);
        return 0;
    }
  • 相关阅读:
    java数据库连接池dbcp的使用
    图片轮显效果大全
    W5500问题集锦(持续更新中)
    Gamma校正及其OpenCV实现
    GlusterFS源代码解析 —— GlusterFS 日志
    cocos2dx 以子弹飞行为例解说拖尾效果类CCMotionStreak
    leetcode__Convert Sorted List to Binary Search Tree
    昨天面试新浪 java试题
    linux概念之性能调优
    Java实现 黑洞数
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9605203.html
Copyright © 2011-2022 走看看