• HDU-4691 Front compression 后缀数组


      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691

      后缀数组模板题,求出Height数组后,对Height做RMQ,然后直接统计就可以了。。。

      1 //STATUS:C++_AC_828MS_11284KB
      2 #include <functional>
      3 #include <algorithm>
      4 #include <iostream>
      5 //#include <ext/rope>
      6 #include <fstream>
      7 #include <sstream>
      8 #include <iomanip>
      9 #include <numeric>
     10 #include <cstring>
     11 #include <cassert>
     12 #include <cstdio>
     13 #include <string>
     14 #include <vector>
     15 #include <bitset>
     16 #include <queue>
     17 #include <stack>
     18 #include <cmath>
     19 #include <ctime>
     20 #include <list>
     21 #include <set>
     22 #include <map>
     23 using namespace std;
     24 //#pragma comment(linker,"/STACK:102400000,102400000")
     25 //using namespace __gnu_cxx;
     26 //define
     27 #define pii pair<int,int>
     28 #define mem(a,b) memset(a,b,sizeof(a))
     29 #define lson l,mid,rt<<1
     30 #define rson mid+1,r,rt<<1|1
     31 #define PI acos(-1.0)
     32 //typedef
     33 typedef __int64 LL;
     34 typedef unsigned __int64 ULL;
     35 //const
     36 const int N=100010;
     37 const int INF=0x3f3f3f3f;
     38 const int MOD=1000000007,STA=8000010;
     39 const LL LNF=1LL<<60;
     40 const double EPS=1e-8;
     41 const double OO=1e15;
     42 const int dx[4]={-1,0,1,0};
     43 const int dy[4]={0,1,0,-1};
     44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
     45 //Daily Use ...
     46 inline int sign(double x){return (x>EPS)-(x<-EPS);}
     47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
     48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
     49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
     50 template<class T> inline T Min(T a,T b){return a<b?a:b;}
     51 template<class T> inline T Max(T a,T b){return a>b?a:b;}
     52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
     53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
     54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
     55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
     56 //End
     57 
     58 char s[N];
     59 int d[N][20];
     60 int num[N];
     61 int sa[N],t1[N],t2[N],c[N],rank[N],height[N];
     62 int n,m;
     63 
     64 void build_sa(int s[],int n,int m)
     65 {
     66     int i,k,p,*x=t1,*y=t2;
     67     //第一轮基数排序
     68     for(i=0;i<m;i++)c[i]=0;
     69     for(i=0;i<n;i++)c[x[i]=s[i]]++;
     70     for(i=1;i<m;i++)c[i]+=c[i-1];
     71     for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
     72     for(k=1;k<=n;k<<=1){
     73         p=0;
     74         //直接利用sa数组排序第二关键字
     75         for(i=n-k;i<n;i++)y[p++]=i;
     76         for(i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
     77         //基数排序第一关键字
     78         for(i=0;i<m;i++)c[i]=0;
     79         for(i=0;i<n;i++)c[x[y[i]]]++;
     80         for(i=1;i<m;i++)c[i]+=c[i-1];
     81         for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
     82         //根据sa和x数组计算新的x数组
     83         swap(x,y);
     84         p=1;x[sa[0]]=0;
     85         for(i=1;i<n;i++)
     86             x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
     87         if(p>=n)break;   //已经排好序,直接退出
     88         m=p;     //下次基数排序的最大值
     89     }
     90 }
     91 
     92 void getHeight(int s[],int n)
     93 {
     94     int i,j,k=0;
     95     for(i=0;i<=n;i++)rank[sa[i]]=i;
     96     for(i=0;i<n;i++){
     97         if(k)k--;
     98         j=sa[rank[i]-1];
     99         while(s[i+k]==s[j+k])k++;
    100         height[rank[i]]=k;
    101     }
    102 }
    103 
    104 void rmq_init(int a[])
    105 {
    106     int i,j;
    107     for(i=1;i<=n;i++)d[i][0]=a[i];
    108     for(j=1;(1<<j)<=n;j++){
    109         for(i=1;i+(1<<j)-1<=n;i++){
    110             d[i][j]=Min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
    111         }
    112     }
    113 }
    114 
    115 int rmq(int l,int r)
    116 {
    117     int k=0;
    118     while((1<<(k+1))<=r-l+1)k++;
    119     return Min(d[l][k],d[r-(1<<k)+1][k]);
    120 }
    121 
    122 int lcp(int a,int b)
    123 {
    124     if(a==b)return n-a;      //a和b为同一后缀,直接输出,字串串长度为n
    125     int ra=rank[a],rb=rank[b];
    126     if(ra>rb)swap(ra,rb);
    127     return rmq(ra+1,rb);
    128 }
    129 
    130 int w[N];
    131 
    132 int main(){
    133  //   freopen("in.txt","r",stdin);
    134     int i,j,k,Q,a,b,la,lb;
    135     LL ans1,ans2,t;
    136     w[0]=1;
    137     for(i=k=1;i<N;i=j,k++)
    138         for(j=i*10;i<j && i<N;i++)w[i]=k;
    139     while(~scanf("%s",s))
    140     {
    141         n=strlen(s);
    142         for(i=0;i<n;i++)
    143             num[i]=s[i]-'a'+1;
    144         num[n]=0;m=27;
    145         build_sa(num,n+1,m);
    146         getHeight(num,n);
    147         rmq_init(height);
    148 
    149         scanf("%d",&Q);
    150         ans1=(LL)Q,ans2=(LL)2*Q;
    151         scanf("%d%d",&la,&lb);
    152         ans1+=(LL)lb-la;ans2+=(LL)lb-la+1;
    153         while(--Q){
    154             scanf("%d%d",&a,&b);
    155             ans1+=(LL)b-a;
    156             t=(LL)Min(lcp(la,a),lb-la,b-a);
    157             ans2+=(LL)b-a-t+w[t];
    158         //    printf("  %I64d %d %d %d
    ",t,lcp(la,a),lb-la,b-a);
    159             la=a;lb=b;
    160         }
    161 
    162         printf("%I64d %I64d
    ",ans1,ans2);
    163 
    164     }
    165     return 0;
    166 }
  • 相关阅读:
    JBoss下配置数据源加密
    线程返回值的方式介绍
    @Async java 异步方法
    spring 源码下载地址
    springmvc maven 入门及页面拿不到controller的值 显示${message} el表达式不起作用
    mysql常用函数
    eclipse 开发常见问题集锦
    linux 常用命令及零散知识
    js一些注意事项
    liunx 免密登录远程主机
  • 原文地址:https://www.cnblogs.com/zhsl/p/3271298.html
Copyright © 2020-2023  润新知