zoukankan      html  css  js  c++  java
  • HDU 4691

    http://acm.hdu.edu.cn/showproblem.php?pid=4691

    留个板子。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cmath>
      6 using namespace std;
      7 const int maxn = 1e5+5;
      8 int t1[maxn],t2[maxn],c[maxn];//求SA数组需要的中间变量,不需要赋值
      9 //待排序的字符串放在s数组中,从s[0]到s[n-1],长度为n,且最大值小于m,
     10 //除s[n-1]外的所有s[i]都大于0,r[n-1]=0
     11 //函数结束以后结果放在sa数组中
     12 bool cmp(int *r,int a,int b,int l)
     13 {
     14     return r[a] == r[b] && r[a+l] == r[b+l];
     15 }
     16 void da(int str[],int sa[],int Rank[],int height[],int n,int m)
     17 {
     18     n++;
     19     int i, j, p, *x = t1, *y = t2;
     20     //第一轮基数排序,如果s的最大值很大,可改为快速排序
     21     for(i = 0;i < m;i++)c[i] = 0;
     22     for(i = 0;i < n;i++)c[x[i] = str[i]]++;
     23     for(i = 1;i < m;i++)c[i] += c[i-1];
     24     for(i = n-1;i >= 0;i--)sa[--c[x[i]]] = i;
     25     for(j = 1;j <= n; j <<= 1)
     26     {
     27         p = 0;
     28         //直接利用sa数组排序第二关键字
     29         for(i = n-j; i < n; i++)y[p++] = i;//后面的j个数第二关键字为空的最小
     30         for(i = 0; i < n; i++)if(sa[i] >= j)y[p++] = sa[i] - j;
     31         //这样数组y保存的就是按照第二关键字排序的结果
     32         //基数排序第一关键字
     33         for(i = 0; i < m; i++)c[i] = 0;
     34         for(i = 0; i < n; i++)c[x[y[i]]]++;
     35         for(i = 1; i < m;i++)c[i] += c[i-1];
     36         for(i = n-1; i >= 0;i--)sa[--c[x[y[i]]]] = y[i];
     37         //根据sa和x数组计算新的x数组
     38         swap(x,y);
     39         p = 1; x[sa[0]] = 0;
     40         for(i = 1;i < n;i++)
     41             x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;
     42         if(p >= n)break;
     43         m = p;//下次基数排序的最大值
     44     }
     45     int k = 0;
     46     n--;
     47     for(i = 0;i <= n;i++)Rank[sa[i]] = i;
     48     for(i = 0;i < n;i++)
     49     {
     50         if(k)k--;
     51         j = sa[Rank[i]-1];
     52         while(str[i+k] == str[j+k])k++;
     53         height[Rank[i]] = k;
     54     }
     55 }
     56 int Rank[maxn],height[maxn];
     57 int sa[maxn];
     58 char s[maxn];
     59 int M[maxn][20];
     60 int r[maxn];
     61 int A[maxn],B[maxn];
     62 void RMQ(int n)
     63 {
     64     for(int i=1;i<=n;i++) M[i][0] = height[i];
     65     for(int j=1;(1<<j)<=n;j++)
     66     {
     67         for(int i=1;(i+(1<<j)-1)<=n;i++)
     68         {
     69             M[i][j] = min(M[i][j-1],M[i+(1<<(j-1))][j-1]);
     70         }
     71     }
     72 }
     73 int ST(int l,int r)
     74 {
     75     int k = 0;
     76     while((1<<(k+1))<=(r-l+1)) k++;
     77     return min(M[l][k],M[r-(1<<k)+1][k]);
     78 }
     79 int lcp(int a,int b)
     80 {
     81     a = Rank[a],b = Rank[b];
     82     if(a>b) swap(a,b);
     83     return ST(a+1,b);
     84 }
     85 int cal(int x)
     86 {
     87     int res = 0;
     88     if(x==0) res++;
     89     while(x)
     90     {
     91         x /= 10;
     92         res++;
     93     }
     94     return res;
     95 }
     96 int main()
     97 {
     98     while(scanf("%s",s)!=EOF)
     99     {
    100         int len = strlen(s);
    101         for(int i=0;i<len;i++) r[i] = s[i];
    102         r[len] = 0;
    103         da(r,sa,Rank,height,len,128);
    104         RMQ(len);
    105         long long ans1 = 0,ans2 = 0;
    106         int T;scanf("%d",&T);
    107         for(int i=1;i<=T;i++)
    108         {
    109             scanf("%d %d",&A[i],&B[i]);
    110             if(i==1)
    111             {
    112                 ans1 += B[i]-A[i]+1;
    113                 ans2 += B[i]-A[i]+3;
    114                 continue;
    115             }
    116             int temp = 0;
    117             if(A[i]!=A[i-1]) temp = lcp(A[i-1],A[i]);
    118             else temp = 1e9;
    119             temp = min(temp,B[i]-A[i]);
    120             temp = min(temp,B[i-1]-A[i-1]);
    121             ans1 += B[i]-A[i]+1;
    122             ans2 += B[i]-A[i]-temp+2;
    123             ans2 += cal(temp);
    124         }
    125         printf("%I64d %I64d
    ",ans1,ans2);
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    Linux各主要发行版的包管理命令对照
    JDK 生成数字证书
    AbatorForEclipse插件使用总结
    [转载]在rhel 6 x86_64 上安装oracle 11g xe
    【转载】PL/SQL配置连接ORACLE
    Archlive新年第一棒: 基于2.6.37稳定内核的archlive20110107
    基于Arch的live系统
    【转】MyEclipse 9.0正式版官网下载(附Win+Llinux激活方法、汉化包)
    Exception in thread main java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFacto
    MyEclipse 8.6插件下载
  • 原文地址:https://www.cnblogs.com/littlepear/p/7339942.html
Copyright © 2011-2022 走看看