zoukankan      html  css  js  c++  java
  • HDU 5008 Boring String Problem(后缀数组+二分)

    题目链接

    思路 想到了,但是木写对啊....代码 各种bug,写的乱死了....

    输出最靠前的,比较折腾...

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    #include <map>
    using namespace std;
    #define N 501000
    #define LL __int64
    int sa[N],height[N],rank[N];
    int c[N],wa[N],wb[N];
    int p[N];
    int res[N];
    char str[N];
    LL sum[N];
    LL l,r;
    int bin[31];
    int minz[22][N];
    int sz[22][N];
    void build_sa(int s[],int n,int m)
    {
        int i,j,p,*x = wa,*y = wb;
        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(j = 1;j <= n;j <<= 1)
        {
            p = 0;
            for(i = n-j;i < n;i ++)
            y[p++] = i;
            for(i = 0;i < n;i ++)
            if(sa[i] >= j) y[p++] = sa[i] - j;
            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]+j] == y[sa[i]+j]?p-1:p++;
            if(p >= n) break;
            m = p;
        }
    }
    void get_height(int s[],int n)
    {
        int i,j,k = 0;
        for(i = 1;i <= n;i ++)
        rank[sa[i]] = i;
        for(i = 0;i < n;i ++)
        {
            if(k) k--;
            j = sa[rank[i]-1];
            while(s[i+k]==s[j+k]) k ++;
            height[rank[i]] = k;
        }
    }
    void init(int n)
    {
        int i,j;
        for(i = 1; i <= n; i ++)
        {
            minz[0][i] = height[i];
            sz[0][i] = sa[i];
        }
        for(i = 1; bin[i] <= n; i ++)
        {
            for(j = 1; j + bin[i-1] <= n; j ++)
            {
                minz[i][j] = min(minz[i-1][j],minz[i-1][j+bin[i-1]]);
                sz[i][j] = min(sz[i-1][j],sz[i-1][j+bin[i-1]]);
            }
        }
    }
    int rmq(int s,int t)
    {
        s = rank[s];
        t = rank[t];
        if(s > t) swap(s,t);
        s ++;
        int k = log((t-s+1)*1.0)/log(2.0);
        return min(minz[k][s],minz[k][t-bin[k]+1]);
    }
    int rmq1(int s,int t)
    {
        s = rank[s];
        t = rank[t];
        if(s > t) swap(s,t);
        s ++;
        int k = log((t-s+1)*1.0)/log(2.0);
        return min(sz[k][s],sz[k][t-bin[k]+1]);
    }
    void find(LL k,int n)
    {
        int str,end,mid,i;
        str = 1;
        end = n;
        while(str < end)
        {
            mid = (str + end + 1)/2;
            if(sum[mid] > k)
            end = mid - 1;
            else
            str = mid;
        }
        i = end;
        if(sum[end] > k)
        {
            l = sa[i];
            r = sa[i]+k-1;
        }
        else if(k == sum[end])
        {
            l = sa[i];
            r = n-1;
        }
        else
        {
            i ++;
            l = sa[i];
            r = sa[i]  + k - sum[end] + height[i]-1;
        }
        int len = r-l+1;
        if(i == n)
        {
            l ++;
            r ++;
            return ;
        }
        if(height[i+1] < len)
        {
            l ++;
            r ++;
            return ;
        }
        str = i+1;
        end = n;
        while(str < end)
        {
            mid = (str + end + 1)/2;
            if(rmq(sa[i],sa[mid]) < len)
            end = mid - 1;
            else
            str = mid;
        }
        if(rmq(sa[i],sa[end]) >= len)
        {
            l = min(l,(LL)rmq1(sa[i],sa[end]));
            r = l+len-1;
        }
        l ++;
        r ++;
    }
    int main()
    {
        int i,len,n;
        LL maxz;
        for(i = 0; i < 21; i ++)
            bin[i] = 1<<i;
        LL v,k;
        while(scanf("%s",str)!=EOF)
        {
            len = strlen(str);
            for(i = 0;i < len;i ++)
            {
                p[i] = str[i]-'a'+1;
            }
            p[len] = 0;
            build_sa(p,len+1,30);
            get_height(p,len);
            init(len);
            maxz = 0;
            for(i = 1;i  <= len;i ++)
            {
                maxz += len-sa[i]-height[i];
                sum[i] = maxz;
            }
            scanf("%d",&n);
            l = r = 0;
            for(i = 0;i < n;i ++)
            {
                scanf("%I64d",&v);
    //            find(v,len);
    //            printf("%I64d %I64d
    ",l,r);
                 k = (v^l^r)+1;
    
                if(k > maxz)
                {
                    l = r = 0;
                }
                else
                {
                    find(k,len);
                }
                printf("%I64d %I64d
    ",l,r);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HTML5 闹钟例子程序
    程序员书籍,你值得收藏
    mybatis入门案例测试常见问题以及解决方法
    jquery对Select标签的操作
    Linux下mysql整库备份
    Windows 命令提示符下查看 apache 错误的方法
    将 DataTable 转化为 Excel Xml 格式供下载
    Infragistics netadvantage UltraGrid (UltraWinGrid) 编程手记
    报表设计技巧交叉报表模板
    Gentle.NET Users' Guide
  • 原文地址:https://www.cnblogs.com/naix-x/p/3971407.html
Copyright © 2011-2022 走看看