1. 程式人生 > 其它 >AcWing 841. 字串雜湊 2022/5/25

AcWing 841. 字串雜湊 2022/5/25

include

include

using namespace std;
typedef unsigned long long ULL;

char str[N]; //存放字串
int h[N], p[N]; //h[]存放字首和,p[]存放倍數

ULL get(int l, int r){
return h[r] - h[l - 1] * p[r - l + 1];
}

int main(){
int n, m;
int l1, r1, l2, r2;
scanf("%d%d", &n, &m);
p[0] = 1; //個位倍數
for(int i = 1;i <= n; i++){
h[i] = h[i - 1] * P + str[i];
p[i] = p[i - 1] * P;
}
while(m --){
scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
if(get(l1, r1) == get(l2, r2)) puts("Yes");
else puts("No");
}
return 0;
}


核心思想:字串對映為特徵值(字首和)後取模,每個字串對應不同的數字以區分字串是否相同
關鍵步驟:(1)字首和求法:字串從左到右,從高位到低位,h[i] = h[i - 1] * P + str[i];
A B C D h[4]
A B C h[3]
A B h[2]
A h[1]
(2)部分和求法:利用字首和求部分和 h[r] - h[l - 1] * p[l - r + 1];
注意的地方:字串每一位不能對應 0 ,ascall碼 \0 對應 0, 可以避免
p[0] == 1;
p[1] == 1 * 131;
p[2] == 1 * 131 *131;
p[3] == 1 * 131 *131 *131;
……
移除後取模
ULL 對應2 ^ 64