zoukankan      html  css  js  c++  java
  • HDU5442

    HDU5442


    做法:把原串复制一份加在后边,中间插特殊入个特殊字符,再把翻转后的串加在后边,同样复制一份。然后做后缀数组,按题意处理细节即可。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <vector>
    #include <iterator>
    #include <string>
    #include <deque>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define per(i,a,b) for(int i=a;i>=b;--i)
    #define pb push_back
    #define MP make_pair
    #define fr first
    #define sc second
    #define PII pair<int,int>
    #define VI vector<int>
    typedef long long ll;
    typedef unsigned long long ull;
    const int N = 100005;
    inline int readint() {
        char c=getchar();int x=0,f=1;
        while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    using namespace std;
    int n;
    char c[N],str[N];
    int rnk[N] , SA[N] , Height[N];
    int X[N] , Y[N] , sum[N];
    int f[101000][20] , fm[101000][20];
    bool cmp(int *r,int a,int b,int l) {
        return ( r[a] == r[b] && r[a+l] == r[b+l] );
    }
    void calc() {
        int l , p , *x = X , *y = Y , m = 128;
        rep(i,0,m) sum[i] = 0;
        rep(i,1,n) sum[ x[i] = c[i] ] ++;
        rep(i,1,m) sum[i] += sum[i-1];
        per(i,n,1) SA[ sum[ x[i] ]-- ] = i;
        for ( l = 1 , p = 1 ; l <= n ; m = p , l *= 2 ) {
            p = 0;
            rep(i,n-l+1,n) y[++p] = i;
            rep(i,1,n) if ( SA[i] > l ) y[++p] = SA[i] - l;
            rep(i,0,m) sum[i] = 0;
            rep(i,1,n) sum[ x[y[i]] ] ++;
            rep(i,1,m) sum[i] += sum[i-1];
            per(i,n,1) SA[ sum[ x[y[i]] ]-- ] = y[i];
            swap( x , y );
            x[SA[1]] = 1; p = 2;
            rep(i,2,n)
                x[ SA[i] ] = cmp(y,SA[i-1],SA[i],l) ? p - 1 : p++;
        }
        rep(i,1,n) rnk[SA[i]] = i;
        p = 0;
        rep(i,1,n) {
            if ( rnk[i] == 1 ) continue;
            while ( c[i+p] == c[SA[rnk[i]-1]+p] ) p ++;
            Height[rnk[i]] = p;
            if ( p ) p --;
        }
    }
    void init() {
        n = strlen(str);
        int cc = 0;
        for(int i=0;i<n;++i) c[++cc] = str[i];
        for(int i=0;i<n;++i) c[++cc] = str[i];
        c[++cc] = '$';
        for(int i=n-1;i>=0;--i) c[++cc] = str[i];
        for(int i=n-1;i>=0;--i) c[++cc] = str[i];
        c[cc+1]=0;
        n = cc;
    }
    int Log[N],rmq[N][30];
    void init_rmq() {
        Log[1] = 0;
        for(int i=2;i<=n;++i) Log[i] = Log[i>>1] + 1;
        for(int i=1;i<=n;++i) rmq[i][0] = Height[i];
        for(int j=1;j<=20;++j)
            for(int i=1;i+(1<<(j-1))<=n;++i)
                rmq[i][j] = min(rmq[i][j-1],rmq[i+(1<<j-1)][j-1]);
    }
    int RMQ_mn(int l,int r){
        int L=Log[r-l+1];
        return min(rmq[l][L],rmq[r-(1<<L)+1][L]);
    }
    int ask(int x,int y) {
        x=rnk[x],y=rnk[y];
        if(x>y)swap(x,y);
        return RMQ_mn(x+1,y);
    }
    int T, num;
    int biao(int x) {
        if(x <= num) return x;
        return num - (x-num*2-1) + 1;
    }
    int cal_s(int x) {
        if(x<=num) return 0;
        return 1;
    }
    int main() {
        scanf("%d",&T);
        while(T--) {
            scanf("%d",&num);
            scanf(" %s",str);
            init();
            calc();
            init_rmq();
            int idx = n;
            int ansb = biao(SA[n]), anss = cal_s(SA[n]);
            for(int i=n;i>=1;--i) if(SA[i]!=num*2+1){
                if(SA[i]<=num) {
                    idx = i;
                    ansb = biao(SA[i]);
                    anss = cal_s(SA[i]);
                    break;
                }
                if(SA[i]>=2*num+1&&SA[i]<=3*num+1) {
                    idx = i;
                    ansb = biao(SA[i]);
                    anss = cal_s(SA[i]);
                    break;
                }
            }
            for(int i=idx-1;i>=1;--i) if(SA[i] != num*2+1) {
                if(SA[i]>num&&SA[i]<=num*2+1) continue;
                if(SA[i]>3*num+1) continue;
                int lcp = ask(SA[idx],SA[i]);
                if(lcp >= num) {
                    int b = biao(SA[i]), s = cal_s(SA[i]);
                    if(b<ansb) ansb = b,anss=s;
                    else if(b==ansb&&s < anss) ansb=b,anss=s;
                }
            }
            printf("%d %d
    ",ansb,anss);
        }
        return 0;
    }
    
    
  • 相关阅读:
    转载 --ios 模型-setValuesForKeysWithDictionary
    转载 ----HTML5 ---js实现json方式提交数据到服务端
    转载 项目经理需要修炼的9件事
    转载 人生,没有那么简单
    HTML5 ---localStorage储存实例
    HTML5 ---localStorage
    HTML5 --照抄书里的代码但函数无法执行、求分析( Uncaught ReferenceError: xxx is not defined)
    html5 -js判断undefined类型
    python-打印简单公司员工信息表
    python练习程序_员工信息表_基本实例
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9624608.html
Copyright © 2011-2022 走看看