51Nod 演算法馬拉松28 B題 相似子串 雜湊

2022-03-31 16:19:17 字數 1398 閱讀 2893

-zhouzhendong

兩個字串相似定義為:

1.兩個字串長度相等

2.兩個字串對應位置上有且僅有至多乙個位置所對應的字元不相同

給定乙個字串,每次詢問兩個子串在給定的規則下是否相似。給定的規則指每次給出一些等價關係,如『a'=』b',『b'=』c'等,注意這裡的等價關係具有傳遞性,即若『a'=』b',『b'=』c',則『a'=』c'。

我們弄乙個可以通過字首求得區間某乙個字母的排列的雜湊。

然後判斷兩個字串是否相等,就是把該區間所有的字母的雜湊值整合起來。

具體看**。

然後就是二分。

如果兩個串完全相等,那麼yes。

我們二分,取乙個mid,對於mid來說:

如果 左串1≠左串2 且 右串1≠右串2,那麼可以確定是no了。

否則 如果 左串1≠左串2,那麼繼續弄左串,否則繼續弄右串。

時間複雜度:n*26*logn ≈ 1e8而且常數較大。

但是時限有5s,所以可以過去。

#include #include #include #include #include using namespace std;

typedef long long ll;

const int l=300000+5;

ll p=233333333,mod=1000000007,inv=474576274;

int n,m,a[l],fa[26];

ll ha[l][26],pow[l];

char str[l];

int getf(int k)

ll gethash(int l,int r)

return hash;

}int main()

scanf("%d",&m);

while (m--)

if (r1-l1+1!=r2-l2+1)

if (gethash(l1,r1)==gethash(l2,r2))

bool flag=1;

int le=1,ri=r1-l1+1,mid;

while (le>1;

ll hal1=gethash(l1+le-1,l1+mid-1);

ll hal2=gethash(l2+le-1,l2+mid-1);

ll har1=gethash(l1+mid,l1+ri-1);

ll har2=gethash(l2+mid,l2+ri-1);

if (hal1!=hal2&&har1!=har2)

if (hal1!=hal2)

ri=mid;

else

le=mid+1;

} puts(flag?"yes":"no");

} return 0;

}

51nod演算法馬拉松32

比賽鏈結 馬拉松是真的難 應該是我太菜了tnt 同bzoj1534 題解戳這裡 n個有標號的點,其中m個是葉子節點。問有多少數的形態。include include include include include using namespace std typedef long long ll co...

51nod演算法馬拉松15

智力徹底沒有了。看來再也拿不到獎金了qaq。a b君的遊戲 因為資料是9b1l,所以我們可以hash試一下資料。include include include include define rep i,s,t for int i s i t i define dwn i,s,t for int i ...

51nod演算法馬拉松13

a 取餘最長路 不難發現路徑可以拆成三條線段,只要知道兩個轉折點的位置就能計算出答案。設sum i,l,r 表示第i行從l到r元素的和,則答案可以表示為sum 1,1,x sum 2,x,y sum 3,y,n p。字首和一下轉化成 s3 n s3 y 1 s2 y s1 x s2 x 1 p,從小...