兩個字串相似定義為:
1.兩個字串長度相等
2.兩個字串對應位置上有且僅有至多乙個位置所對應的字元不相同
給定乙個字串,每次詢問兩個子串在給定的規則下是否相似。給定的規則指每次給出一些等價關係,如『a'=』b',『b'=』c'等,注意這裡的等價關係具有傳遞性,即若『a'=』b',『b'=』c',則『a'=』c'。
第一行乙個字串s(1<=|s|<=300000)
第二行乙個整數t(1<=t<=300000)
對於每次詢問:
第一行5個整數k,l1,r1,l2,r2,表示有k個等價規則,詢問的是子串[l1,r1],l2,r2
接下來k行每行兩個連續的字元表示這兩個字元等價。
此題中所有的字元均為小寫字母。
t行,若相似則輸出「yes」否則輸出「no」
abac
31 1 2 3 4
bc1 1 2 3 4
ac1 1 2 2 3
acyes
yesno
如果想要得到兩個字串是否相似,也就是說允許有乙個字元不一樣,那麼不妨分為左邊和右邊兩部分分別比較。如果兩邊完全一樣,自然原來的兩個字串也是相似的;如果兩邊都不一樣,那麼不可能做到只有乙個字元不一樣,也就是說兩個字串不相似。當只有一邊是一樣的時候,就去驗證不一樣的那一半,這就是乙個子問題了。
接下來的問題是如何比較兩個字串是否相等。可以用雜湊來解決。由於會出現相同規則的更改,用並查集維護相同字母的關係,然後分字母進行雜湊,最後計算時在合併即可。
#include #include #include #define int long long
#define n 300002
using namespace std;
const int p=199999;
const int mod=1000000007;
int t,l,i,j,fa[30],k,l1,r1,l2,r2,hash[n][30],poww[n];
char s[n];
int id(char x)
int find(int x)
int hash(int l,int r)
return ans;
}signed main()
while(t--)
bool flag=1;
while(l1else if(h1==h3&&h2==h4) break;
else if(h1==h3) l1=mid1+1,l2=mid2+1;
else r1=mid1,r2=mid2;
} if(flag) puts("yes");
else puts("no");
} return 0;
}
51Nod1753 相似子串
兩個字串相似定義為 1.兩個字串長度相等 2.兩個字串對應位置上有且僅有至多乙個位置所對應的字元不相同 給定乙個字串,每次詢問兩個子串在給定的規則下是否相似。給定的規則指每次給出一些等價關係,如 a b b c 等,注意這裡的等價關係具有傳遞性,即若 a b b c 則 a c input 第一行乙...
3230 相似子串
輸入第1行,包含3個整數n,q。q代表詢問組數。第2行是字串s。接下來q行,每行兩個整數i和j。1 i j 輸出共q行,每行乙個數表示每組詢問的答案。如果不存在第i個子串或第j個子串,則輸出 1。5 3ababa 3 55 9 8 10 1816 1樣例解釋 第1組詢問 兩個子串是 aba abab...
bzoj 3230 相似子串
time limit 20 sec memory limit 128 mb submit 1767 solved 438 submit status discuss 輸入第1行,包含3個整數n,q。q代表詢問組數。第2行是字串s。接下來q行,每行兩個整數i和j。1 i j 輸出共q行,每行乙個數表示...