HDU 4029 Distinct Sub-matrix(11年上海熱身 尾碼數組)

來源:互聯網
上載者:User

轉載請註明出處,謝謝http://blog.csdn.net/acm_cxlove/article/details/7854526      
by---cxlove 

題目:給出一個字母矩陣,求出有多少個不相同的子矩陣

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

嘛,似乎可以暴力的

首先枚舉寬度,然後對每一個寬度進行HASH,hash[i][j]表示第i行,從第j個字元開始的w個字元的HASH值。

然後把起點相同的列,連在一起,也就 是豎著把每一列連在一起,列與列之間用一個特殊字元隔開,變成了一個串

剩下的就是求這個串有多少個不同的子串。

可以求出總共有多少個子串,然後利用尾碼數組,通過height數組可以求出有多少個重複的子串,減去即可。

糾結的問題是如何HASH,真是弱爆了。其實我不知道字串HASH,不需要管溢出

每一位設一個權值,原本以為可能衝突會比較嚴重,還準備多重HASH,結果把權值設為26也一次就過了。。。

HASH值範圍大,而且可能有負的,所以離散化一下,map隨便搞搞吧

之後就是求出尾碼數組,這裡debug半天,果斷還是對模板不理解,哭~~~不過過了範例之後還是順利的1Y

#include<iostream>#include<cstdio>#include<map>#include<cstring>#include<cmath>#include<vector>#include<queue>#include<algorithm>#include<set>#define inf (1ull<<63)-1#define N 130#define maxn 100005#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define pb(a) push_back(a)#define mem(a,b) memset(a,b,sizeof(a))#define eps 1e-9#define zero(a) fabs(a)<eps#define ULL unsigned long long#define lson (step<<1)#define rson (step<<1|1)#define MOD 1000000007#define mp(a,b) make_pair(a,b)using namespace std;const ULL hash1=26;struct HASH{ULL h1;HASH(){}HASH(ULL _h1):h1(_h1){}}h[N][N];//以下為倍增演算法求尾碼數組  int wa[maxn],wb[maxn],wv[maxn],Ws[maxn];  int cmp(int *r,int a,int b,int l)  {return r[a]==r[b]&&r[a+l]==r[b+l];}  void da(const int *r,int *sa,int n,int m){      int i,j,p,*x=wa,*y=wb,*t;       for(i=0;i<m;i++) Ws[i]=0;       for(i=0;i<n;i++) Ws[x[i]=r[i]]++;       for(i=1;i<m;i++) Ws[i]+=Ws[i-1];       for(i=n-1;i>=0;i--) sa[--Ws[x[i]]]=i;       for(j=1,p=1;p<n;j*=2,m=p){           for(p=0,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<n;i++) wv[i]=x[y[i]];           for(i=0;i<m;i++) Ws[i]=0;           for(i=0;i<n;i++) Ws[wv[i]]++;           for(i=1;i<m;i++) Ws[i]+=Ws[i-1];           for(i=n-1;i>=0;i--) sa[--Ws[wv[i]]]=y[i];           for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)               x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;       }       return;   }  int sa[maxn],Rank[maxn],height[maxn];  //求height數組  void calheight(const int *r,int *sa,int n){      int i,j,k=0;  for(i=1;i<=n;i++) Rank[sa[i]]=i;     for(i=0;i<n;height[Rank[i++]]=k)          for(k?k--:0,j=sa[Rank[i]-1];r[i+k]==r[j+k];k++);      return;  }    int tot,r[maxn],cnt;char str[N][N];int main(){int t,cas=0,n,m;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=0;i<n;i++) scanf("%s",str[i]);mem(h,0);ULL ans=0;for(int w=1;w<=m;w++){tot=1;cnt=0;map<ULL,int> map;map.clear();for(int i=0;i<n;i++){for(int j=0;j+w-1<m;j++){h[i][j].h1=h[i][j].h1*hash1+str[i][j+w-1]-'A';if(map.find(h[i][j].h1)==map.end())map.insert(mp(h[i][j].h1,tot++));}}for(int j=0;j+w-1<m;j++){for(int i=0;i<n;i++){r[cnt++]=map[h[i][j].h1];}r[cnt++]=tot++;}r[cnt]=0;da(r,sa,cnt+1,tot);calheight(r,sa,cnt);ULL tmp=(n*(n+1)/2)*(m-w+1);for(int i=1;i<=cnt;i++){tmp-=height[i];}ans+=tmp;}printf("Case #%d: %I64u\n",++cas,ans);}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.