• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            算法學(xué)社
            記錄難忘的征途
            posts - 141,comments - 220,trackbacks - 0
            由于這周初學(xué)SAM,變找些題在做。有了SAM,很多問(wèn)題都變簡(jiǎn)單了,比如這題。。。
            題目描述:
               詢問(wèn)兩個(gè)長(zhǎng)度為100,000的字符串,不小于k的公共子串有多少個(gè)。
            算法分析:
               對(duì)一個(gè)串建立SAM,并預(yù)處理出某個(gè)節(jié)點(diǎn)可以匹配的串的終點(diǎn)位置的個(gè)數(shù),另一個(gè)串在上面跑。
               跑的同時(shí)記錄最大可匹配范圍len。
               如果匹配到某個(gè)點(diǎn),len的值大于k了。那么就說(shuō)明該統(tǒng)計(jì)能匹配的串然后加入到answer中了。

               這個(gè)統(tǒng)計(jì)應(yīng)該是不斷回溯這個(gè)節(jié)點(diǎn)的父親。而且對(duì)于某個(gè)k,除了第一個(gè)點(diǎn),其他的點(diǎn)答案都是一樣,于是可以記憶化。

             1 #include<iostream>
             2 #include<algorithm>
             3 #include<cstdio>
             4 #include<cstring>
             5 using namespace std;
             6 const int N = (int)1e5+10;
             7 char ch[N],pat[N];
             8 int par[N<<1], G[N<<1][60], val[N<<1], sz, last;
             9 inline int convert(char x){if(x >= 'a' && x <= 'z'return x - 'a'else return x - 'A' + 26;}
            10 void ins(int x){
            11     int p = last , np = sz ++;
            12     memset(G[np],0,sizeof(G[np]));
            13     val[np] = val[p] + 1;
            14     while(p!=-1&&G[p][x]==0)G[p][x]=np,p=par[p];
            15     if(p==-1){
            16         par[np]=0;
            17     } else {
            18         int q=G[p][x];
            19         if(val[q]==val[p]+1) par[np]=q;
            20         else {
            21             int nq = sz ++;
            22             val[nq] = val[p]+1;
            23             memcpy(G[nq],G[q],sizeof(G[q]));
            24             par[nq] = par[q];
            25             par[q] = par[np] = nq;
            26             while(p!=-1 && G[p][x]==q) G[p][x]=nq, p=par[p];
            27         }
            28     }
            29     last = np;
            30 }
            31 int cnt[N<<1];
            32 struct node{
            33     int id,v;
            34     node(){};
            35     node(int _id,int _v):id(_id),v(_v){}
            36     bool operator < (const node& a)const{
            37         return v > a.v;
            38     }
            39 } num[N<<1];
            40 long long dp[N<<1];
            41 void build(){
            42     sz = 1; last = 0; val[0= 0; par[0= -1;
            43     memset(G[0],0,sizeof(G[0]));
            44     int n = strlen(ch);
            45     for(int i = 0; i < n; i++) ins(convert(ch[i]));
            46     //for(int i = 0; i < sz; i++) cout<<G[i]['x'-'a']<< endl;
            47     for(int i = 0; i < sz; i++) dp[i] = -1, cnt[i] = 0;
            48     int p = last;
            49     while(p) cnt[p]=1, p = par[p];
            50     for(int i = 0; i < sz; i++) num[i] = node(i,val[i]);
            51     sort(num,num+sz);
            52     for(int i = 0; i < sz; i++){
            53         int u = num[i].id,v;
            54         for(int i = 0; i < 60; i++if(v = G[u][i]) {
            55             cnt[u] += cnt[v];
            56         }
            57     }
            58     //for(int i = 0; i < sz; i++) cout<< cnt[i] <<" ";cout<<endl;
            59 }
            60 long long dfs(int p,int k){
            61     long long &ans = dp[p];
            62     if(ans != -1return ans ;
            63     if(val[par[p]] >= k) {
            64         ans = dfs(par[p],k) + 1LL* (val[p] - val[par[p]]) * cnt[p];
            65     } else {
            66         ans = 1LL * (val[p] - k + 1* cnt[p];
            67     }
            68     return ans ;
            69 }
            70 long long solve(int k){
            71     int n = strlen(pat), len = 0, p = 0;
            72     long long ans = 0;
            73     for(int i = 0; i < n; i ++) {
            74         int x= convert(pat[i]);
            75         while(p && G[p][x] == 0) p = par[p], len = val[p];
            76         if(p = G[p][x]){
            77             len ++;
            78             if(len >= k) {
            79                 if(val[par[p]] >= k) ans += 1LL * (len - val[par[p]]) * cnt[p] + dfs(par[p], k);
            80                 else ans += 1LL * (len - k + 1* cnt[p];
            81             }
            82         }
            83 //        cout<< pat[i] <<" "<< ans <<" "<<len<<" "<<p<<endl;
            84     }
            85     return ans ;
            86 }
            87 int main(){
            88     int k ;
            89     while(~scanf("%d",&k)&&k){
            90         scanf("%s%s",ch,pat);
            91         build();
            92         cout<< solve(k) << endl;
            93     }
            94 }
            95 

            posted on 2012-10-25 19:23 西月弦 閱讀(585) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 解題報(bào)告
            亚洲精品tv久久久久| 香蕉99久久国产综合精品宅男自| 久久狠狠爱亚洲综合影院| 亚洲国产欧美国产综合久久| 久久香蕉超碰97国产精品 | 国产精品久久久久久一区二区三区| 久久91精品国产91久久麻豆| 久久久精品久久久久特色影视| 国产成人精品综合久久久| 久久久久久久尹人综合网亚洲| 久久久久这里只有精品| 久久久久无码精品国产不卡| 久久久国产精品| 999久久久国产精品| 欧美大香线蕉线伊人久久| 久久久久无码专区亚洲av| 久久偷看各类wc女厕嘘嘘| 久久久久久免费视频| 色综合久久天天综合| AV狠狠色丁香婷婷综合久久 | 亚洲第一极品精品无码久久| 夜夜亚洲天天久久| …久久精品99久久香蕉国产| 亚洲午夜精品久久久久久浪潮 | 日产精品久久久久久久| 精品久久久久久久国产潘金莲 | 久久99精品久久久久久久不卡| 久久综合色之久久综合| 久久久久综合中文字幕| 久久精品成人欧美大片| 久久99久久成人免费播放| 久久九九亚洲精品| 国产精品久久久久久一区二区三区| 亚洲AV日韩精品久久久久久久| 偷窥少妇久久久久久久久| 久久久久亚洲AV成人网人人网站 | 久久午夜无码鲁丝片午夜精品| 色综合久久久久网| 日韩久久久久中文字幕人妻| 久久人妻少妇嫩草AV蜜桃| 亚洲国产成人久久综合碰|