您的位置:首页 > 其它

【BZOJ2795】[Poi2012]A Horrible Poem【Hash】【GCD】【暴力】

2016-07-14 12:12 405 查看
【题目链接】

【POPOQQQ的题解】

跑了倒数rk5...

/* Think Thank Thunk */
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;

const int maxn = 500005;

int n, m, sum[26][maxn];
char str[maxn];
ULL hash[2][maxn], power[2][maxn], seed[] = {233, 997}, mod[] = {1000000009, 1000000007};

inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}

inline int gcd(int a, int b) {
for(; b; b ^= a ^= b ^= a %= b);
return a;
}

inline bool check(int l, int r, int len) {
len = r - l + 1 - len;
for(int j = 0; j < 2; j++) {
ULL a = (hash[j][l + len - 1] + mod[j] - (hash[j][l - 1] * power[j][len]) % mod[j]) % mod[j];
ULL b = (hash[j][r] + mod[j] - (hash[j][r - len] * power[j][len]) % mod[j]) % mod[j];
if(a != b) return 0;
}
return 1;
}

inline int query(int l, int r) {
int len = r - l + 1;
int k = len;
for(int i = 0; i < 26; i++) k = gcd(k, sum[i][r] - sum[i][l - 1]);

int res = len;
for(int i = 1; i * i <= k; i++) if(k % i == 0) {
if(check(l, r, len / i)) res = min(res, len / i);
if(check(l, r, len / (k / i))) res = min(res, len / (k / i));
}
return res;
}

int main() {
n = iread();
scanf("%s", str + 1);

for(int j = 0; j < 26; j++) for(int i = 1; i <= n; i++)
sum[j][i] = sum[j][i - 1] + (str[i] == (j + 'a'));
power[0][0] = power[1][0] = 1;
for(int j = 0; j < 2; j++) for(int i = 1; i <= n; i++) {
hash[j][i] = (hash[j][i - 1] * seed[j] + (str[i] - 'a')) % mod[j];
power[j][i] = (power[j][i - 1] * seed[j]) % mod[j];
}

m = iread();
while(m--) {
int l = iread(), r = iread();
printf("%d\n", query(l, r));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: