zoukankan      html  css  js  c++  java
  • HDU5769-Substring-多校#4-1006-后缀数组

    给定一个字符x和一个字符串。要求输出包含此字符的所有不同字串。

    后缀数组可以计算一个字符串的所有不同字串,理解了原理就能做这题了。

    对于每一个后缀i,将产生len-sa[i]-hight[i]的前缀,累加起来就是所有不同字串。这里要求字串必须包含x

    也就是对于每一个后缀i,要减去不含x的前缀。

    保存每一个x的位置,用lower_bound查询在此后缀中的第一个x,然后之前的都不计算到贡献当中。

    dc3敲起来太慢了

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #define LL long long
      5 //using namespace std;
      6 
      7 const int maxn = 1e5+100;
      8 #define F(x) ((x)/3+((x)%3 == 1?0:tb))
      9 #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
     10 int wa[maxn*3],wb[maxn*3],wv[maxn*3],wss[maxn*3];
     11 
     12 int c0(int *r,int a,int b)
     13 {
     14     return r[a] == r[b] && r[a+1] == r[b+1] && r[a+2] == r[b+2];
     15 }
     16 int c12(int k,int *r,int a,int b)
     17 {
     18     if(k == 2)
     19         return r[a] < r[b] ||(r[a] == r[b] && c12(1,r,a+1,b+1));
     20     else
     21         return r[a] < r[b] ||(r[a] == r[b] && wv[a+1] < wv[b+1]);
     22 }
     23 void sort(int *r,int *a,int *b,int n,int m)
     24 {
     25     int i;
     26     for(i=0;i<n;i++) wv[i] = r[a[i]];
     27     for(i=0;i<m;i++) wss[i] = 0;
     28     for(i=0;i<n;i++) wss[wv[i]]++;
     29     for(i=1;i<m;i++) wss[i] += wss[i-1];
     30     for(i=n-1;i>=0;i--)b[--wss[wv[i]] ] = a[i];
     31 }
     32 void dc3(int *r,int *_sa,int n,int m)
     33 {
     34     int i,j,*rn = r+n;
     35     int *san = _sa+n,ta = 0,tb=(n+1)/3,tbc=0,p;
     36     r[n] = r[n+1] = 0;
     37     for(i=0;i<n;i++) if(i%3 != 0) wa[tbc++] = i;
     38     sort(r+2,wa,wb,tbc,m);
     39     sort(r+1,wb,wa,tbc,m);
     40     sort(r,wa,wb,tbc,m);
     41     for(p=1,rn[F(wb[0])] = 0,i=1;i<tbc;i++)
     42         rn[F(wb[i])] = c0(r,wb[i-1],wb[i]) ? p-1:p++;
     43     if(p < tbc) dc3(rn,san,tbc,p);
     44     else for(i=0;i<tbc;i++) san[rn[i]] = i;
     45     for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++] = san[i]*3;
     46     if(n%3==1) wb[ta++] = n-1;
     47     sort(r,wb,wa,ta,m);
     48     for(i=0;i<tbc;i++) wv[wb[i]=G(san[i]) ] = i;
     49     for(i=0,j=0,p=0;i<ta&&j<tbc;p++)
     50         _sa[p] = c12(wb[j]%3,r,wa[i],wb[j]) ? wa[i++]:wb[j++];
     51     for(;i<ta;p++) _sa[p] = wa[i++];
     52     for(;j<tbc;p++) _sa[p] = wb[j++];
     53 }
     54 void da(int str[],int _sa[],int _rank[],int _height[],int n,int m)
     55 {
     56     for(int i=n;i<n*3;i++) str[i] = 0;
     57     dc3(str,_sa,n+1,m);
     58     int i,j,k = 0;
     59     for(i=1;i<=n;i++) _rank[_sa[i]] = i;
     60     for(i=0;i<n;i++)
     61     {
     62         if(k) k--;
     63         j = _sa[_rank[i]-1 ];
     64         while(str[i+k] == str[j+k]) k++;
     65         _height[_rank[i]] = k;
     66     }
     67 }
     68 
     69 int T;
     70 int sa[3*maxn],hehe[3*maxn],rank[maxn],height[maxn];
     71 int x;
     72 char line[3*maxn];
     73 
     74 void debug(int n)
     75 {
     76     for(int i=0;i<=n;i++)
     77     {
     78         printf("sa:%d rank:%d height:%d
    ",sa[i],rank[i],height[i]);
     79     }
     80 }
     81 
     82 int main()
     83 {
     84     //freopen("input.txt","r",stdin);
     85     scanf("%d ",&T);
     86     int cas = 0;
     87     while(T--)
     88     {
     89         scanf(" %c %s",&x,line);
     90         int len = strlen(line);
     91         for(int i=0;i<len;i++) hehe[i] = line[i];
     92         int ch[maxn],cnt = 0;
     93         for(int i=0;i<len;i++)
     94         {
     95             if(line[i] == x) ch[cnt++] = i;
     96         }
     97         ch[cnt++] = len;
     98         da(hehe,sa,rank,height,len,300);
     99         //debug(len);
    100         LL ans = 0;
    101         for(int i=1;i<=len;i++)
    102         {
    103             int pos = ch[std::lower_bound(ch,ch+cnt,sa[i]) - ch] - sa[i];
    104             ans += len -sa[i]  ;
    105             ans -= std::max(pos,height[i]);
    106         }
    107         printf("Case #%d: %I64d
    ",++cas,ans);
    108     }
    109 }
  • 相关阅读:
    递延收益
    企业收到政府补助的核算方法
    总额法
    发行股票手续费为什么冲减资本公积
    溢价发行
    融资筹资的区别是什么
    资本公积转增股本
    认股权证和股票期权有什么区别?
    postgresql 锁表查询语句
    生成不带版本的jar包 不影响deploy
  • 原文地址:https://www.cnblogs.com/helica/p/5743112.html
Copyright © 2011-2022 走看看