poj 2774 二分+hash

poj 2774
求兩個字符串的最長公共子串,可以二分長度菱涤,把A串中長度為mid的子串的hash值存入hash table里(set map也可)晶通,在B串中枚舉子串判斷是否存在hash table里项钮。hash的常數(shù)較大渣叛,比后綴數(shù)組丈秩、后綴自動機的解法較慢,模板長度也不小(我的代碼用雙hash淳衙,第一個hash檢索table中的下標蘑秽,第二個hash判斷沖突時是否相等,hash_table中的tim作為計數(shù)器箫攀,用來初始多組數(shù)據(jù)肠牲,避免多次memset超時)。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn=1e5+100;
const int ha1=443,ha2=317,mod=1000099;
struct Point
{
    int x,y;
    Point(int a=0,int b=0) { x=a,y=b; }
    friend Point operator + (const Point &a,const Point &b)
    {
        return Point((a.x+b.x) % mod,(a.y+b.y) % mod);
    }
    friend Point operator - (const Point &a,const Point &b)
    {
        return Point((a.x-b.x+mod) % mod,(a.y-b.y+mod) % mod);
    }
    friend Point operator * (const Point &a,const Point &b)
    {
        return Point((long long)a.x*b.x % mod, (long long)a.y*b.y % mod);
    }
    friend bool operator == (const Point &a,const Point &b)
    {
        return (a.x==b.x && a.y==b.y);
    }
};

struct hash_table
{
    int tim;
    int vis[mod],key2[mod];

    hash_table()
    {
        tim=0;
        memset(vis,0,sizeof(vis));
        memset(key2,0,sizeof(key2));
    }
    void init()
    {
        tim++;
    }
    int get_pos(const Point &a)
    {
        int pos=a.x,v=a.y;
        for (; vis[pos]==tim && key2[pos]!=v; pos+=11,pos%=mod);
        return pos;
    }
    void insert(const Point &a)
    {
        int pos=get_pos(a);
        vis[pos]=tim;
        key2[pos]=a.y;
    }
    bool find(const Point &a)
    {
        int pos=get_pos(a);
        return (vis[pos]==tim);
    }
};

Point po[maxn],sum1[maxn],sum2[maxn];
hash_table HT;
char A[maxn],B[maxn];
int N,M;

void Prepare_hash()
{
    po[0]=Point(1,1);
    po[1]=Point(ha1,ha2);
    for (int i=2; i<maxn; i++)
        po[i]=po[i-1]*po[1];
}

void get_hash(char *s,Point *sum,int len)
{
    sum[0]=Point(0,0);
    for (int i=1; i<=len; i++)
        sum[i]=sum[i-1]+po[i]*Point(s[i],s[i]);
}

bool check(int len)
{
    int U=max(N,M);
    HT.init();
    for (int i=1; i<=N-len+1; i++)
    {
        Point p=sum1[i+len-1]-sum1[i-1];
        p=p*po[U-i];
        HT.insert(p);
    }
    for (int i=1; i<=M-len+1; i++)
    {
        Point p=sum2[i+len-1]-sum2[i-1];
        p=p*po[U-i];
        if (HT.find(p)) return true;
    }
    return false;
}

int main()
{
    Prepare_hash();
    for (; scanf("%s%s",A+1,B+1)!=EOF; )
    {
        N=strlen(A+1);
        M=strlen(B+1);
        get_hash(A,sum1,N);
        get_hash(B,sum2,M);
        int le=0,ri=min(N,M)+1;
        while(le+1<ri)
        {
            int mid=(le+ri)>>1;
            check(mid) ? le=mid : ri=mid;
        }
        printf("%d\n",le);
    }
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末靴跛,一起剝皮案震驚了整個濱河市缀雳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梢睛,老刑警劉巖肥印,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扬绪,居然都是意外死亡竖独,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門挤牛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人种蘸,你說我怎么就攤上這事墓赴。” “怎么了航瞭?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵诫硕,是天一觀的道長。 經(jīng)常有香客問我刊侯,道長章办,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮藕届,結(jié)果婚禮上挪蹭,老公的妹妹穿的比我還像新娘。我一直安慰自己休偶,他們只是感情好梁厉,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著踏兜,像睡著了一般词顾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碱妆,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天肉盹,我揣著相機與錄音,去河邊找鬼疹尾。 笑死垮媒,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的航棱。 我是一名探鬼主播睡雇,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼饮醇!你這毒婦竟也來了它抱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤朴艰,失蹤者是張志新(化名)和其女友劉穎观蓄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祠墅,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡侮穿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了毁嗦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亲茅。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狗准,靈堂內(nèi)的尸體忽然破棺而出克锣,到底是詐尸還是另有隱情,我是刑警寧澤腔长,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布袭祟,位于F島的核電站,受9級特大地震影響捞附,放射性物質(zhì)發(fā)生泄漏巾乳。R本人自食惡果不足惜您没,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胆绊。 院中可真熱鬧氨鹏,春花似錦、人聲如沸辑舷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽何缓。三九已至肢础,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碌廓,已是汗流浹背传轰。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谷婆,地道東北人慨蛙。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像纪挎,于是被迫代替她去往敵國和親期贫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx异袄?那么一定聽過它的“同行”Apache吧通砍!Ngi...
    JokerW閱讀 32,703評論 24 1,002
  • 教你如何迅速秒殺掉:99%的海量數(shù)據(jù)處理面試題 本文經(jīng)過大量細致的優(yōu)化后,收錄于我的新書《編程之法》第六章中烤蜕,新書...
    Helen_Cat閱讀 7,428評論 1 39
  • 作者:July封孙、wuliming、pkuoliver 說明:本文分為三部分內(nèi)容讽营,第一部分為一道百度面試題Top K...
    cyj_ya閱讀 820評論 0 0
  • 【視也導(dǎo)讀】從給整車導(dǎo)流到做城際整車垂直創(chuàng)業(yè)橱鹏,福佑卡車單丹丹坦言膜蠢,在這樣的交易場景下,價格是一方面蚀瘸,貨物安全的交付...
    視也閱讀 224評論 0 1
  • 從明天起狡蝶!做一個積極樂觀的人!早起贮勃,運動,打掃房間苏章!不為整潔寂嘉,只為忘卻思念奏瞬! 從明天起,做一個有理想的人...
    綠蘿悠悠閱讀 131評論 0 0