zoukankan      html  css  js  c++  java
  • [poj 3261]后缀数组+滑窗最小值

    题目链接:http://poj.org/problem?id=3261

    这个是可以交叉的重复串,所以用height就可以了,但是题目说让重复k次以上,也就是直接做一个k-1长度的滑窗最小值,从这些最小值里取最大即可。

    这里其实为了节省空间可以先给数字离散化一下,这样就只有20000了,不过不离散化空间也够用。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    const int maxn=1000005;
    
    #define F(x) ((x)/3+((x)%3==1?0:tb))
    #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
    int wa[maxn*3],wb[maxn*3],wv[maxn*3],wss[maxn*3];
    int c0(int *r,int a,int b)
    {
        return r[a]==r[b] && r[a+1]==r[b+1] && r[a+2]==r[b+2];
    }
    int c12(int k,int *r,int a,int b)
    {
        if (k==2) return r[a]<r[b] || (r[a]==r[b]&&c12(1,r,a+1,b+1));
        else return r[a]<r[b] || (r[a]==r[b]&&wv[a+1]<wv[b+1]);
    }
    void sort(int *r,int *a,int *b,int n,int m)
    {
        int i;
        for (i=0;i<n;i++) wv[i]=r[a[i]];
        for (i=0;i<m;i++) wss[i]=0;
        for (i=0;i<n;i++) wss[wv[i]]++;
        for (i=1;i<m;i++) wss[i]+=wss[i-1];
        for (i=n-1;i>=0;i--) b[--wss[wv[i]]]=a[i];
    }
    void dc3(int *r,int *sa,int n,int m)
    {
        int i,j,*rn=r+n;
        int *san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;
        r[n]=r[n+1]=0;
        for (i=0;i<n;i++) if (i%3!=0) wa[tbc++]=i;
        sort(r+2,wa,wb,tbc,m);
        sort(r+1,wb,wa,tbc,m);
        sort(r,wa,wb,tbc,m);
        for (p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++)
            rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++;
        if (p<tbc) dc3(rn,san,tbc,p);
        else for (i=0;i<tbc;i++) san[rn[i]]=i;
        for (i=0;i<tbc;i++) if (san[i]<tb) wb[ta++]=san[i]*3;
        if (n%3==1) wb[ta++]=n-1;
        sort(r,wb,wa,ta,m);
        for (i=0;i<tbc;i++) wv[wb[i]=G(san[i])]=i;
        for (i=0,j=0,p=0;i<ta&&j<tbc;p++)
            sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++];
        for (;i<ta;p++) sa[p]=wa[i++];
        for (;j<tbc;p++) sa[p]=wb[j++];
    }
    void da(int str[],int sa[],int rank[],int height[],int n,int m)
    {
        for (int i=n;i<n*3;i++)
            str[i]=0;
        dc3(str,sa,n+1,m);
        int i,j,k=0;
        for (i=0;i<=n;i++) rank[sa[i]]=i;
        for (i=0;i<n;i++)
        {
            if (k) k--;
            j=sa[rank[i]-1];
            while (str[i+k]==str[j+k]) k++;
            height[rank[i]]=k;
        }
    }
    int a[maxn*3];
    int ra[maxn*3],height[maxn*3],sa[maxn*3];
    
    deque< pair<int,int> > q;
    
    int solve(int n,int k)
    {
        // height[2..n]
        // length k-1 min
        int ma=0;
        while (!q.empty()) q.pop_back();
        for (int i=0;i<k-2;i++)
        {
            pair<int,int> p=make_pair(height[i+2],i);
            while (!q.empty()&&q.back()>p) q.pop_back();
            q.push_back(p);
        }
        for (int i=k-2;i<=n-2;i++)
        {
            while (!q.empty() && q.front().second<i-(k-2)) q.pop_front();
            pair<int,int> p=make_pair(height[i+2],i);
            while (!q.empty()&&q.back()>p) q.pop_back();
            q.push_back(p);
            ma=max(ma,q.front().first);
        }
        return ma;
    }
    
    int main()
    {
        int n,k;
        while (~scanf("%d%d",&n,&k))
        {
            for (int i=0;i<n;i++) scanf("%d",&a[i]),a[i]++;
            da(a,sa,ra,height,n,1000002);
            printf("%d
    ",solve(n,k));
        }
        return 0;
    }
  • 相关阅读:
    nmap扫描工具
    cobbler全自动批量安装部署linux
    使用ngxtop实时监控nginx
    Nginx 错误汇总
    定制sudo的密码保持时间以及如何不需要密码
    解决eclipse中出现Resource is out of sync with the file system问题
    log4j:ERROR Category option " 1 " not a decimal integer.错误解决
    properties文件中中文不能显示或者中文乱码
    Log4j使用总结
    eclipse, Log4j配置(真心的详细~)
  • 原文地址:https://www.cnblogs.com/acmsong/p/7223305.html
Copyright © 2011-2022 走看看