提交了整整一页,我恨!TAT
POJ 3261 Milk Patterns
- 题意:找到长度为n的串中出现次数为k的最长子串,子串可以有重叠部分。
- 思路:就很显然的二分+哈希。
但是我为什么交了一页!!!!
- 开始直接while里面直接用了快读,死循环了,跑不出来,T了几发,还以为是算法有问题……www
- <=被我写成了< !!!!!!!! 我????
- mod = 20007 ?????? 不是质数啊!!!!!!! qaq,我哭
就这两个我跟你讲,愣死没找出来bug. ……wwww,最后的最后www随便输了一组样例
10 2
1 1 1 1 1 1 1 1 1 1
- 发现答案不对,于是发现了第二个臭不要脸的bug
- 改了还是WA,心态崩了啊。对照网上的代码,有一篇跟我写的差不多,发现没什么问题啊???什么鬼啊。然后就一句一句的对,发现好像mod不一样,于是就改了和他一样的。shit,就过了!然后想了想20007不是质数啊qaq!!!!!!!!我恨
- 但是后来我又改了mod为小一点的100007,或者1000007,都过不了。就有点诡异。www. 应该是哈希冲突了。
- 中间还写了双哈希的代码,代码附在了最后,双哈希的话用100007就可,没什么限制。
- 这是第一道用了没用ull溢出自动取模的写法!!就给我整成了这个样子,我恨……
AC CODE
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 2e4 + 7;
const int mod = 1000000007;
const ll base = 233;
int read()
{
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
ll p[maxN], Hash[maxN];
int n, k, arr[maxN];
void pre()
{
p[0] = 1;
for(int i = 1; i <= 20000; i ++ ) p[i] = p[i - 1] * base % mod;
}
ll get_hash(int l, int r, ll *g)
{
return (g[r] - g[l - 1] * p[r - l + 1] % mod + mod) % mod;
}
bool judge(int x)
{
ll cnt[maxN]; int tot = 0;
for(int i = 1; i <= n - x + 1; i ++ )
cnt[tot ++ ] = get_hash(i, i + x - 1, Hash);
sort(cnt, cnt + tot);
int ans = 0, num = 1;
ll tar = cnt[0];
for(int i = 1; i < tot; i ++ )
{
if(tar == cnt[i])
++ num;
else
{
tar = cnt[i];
ans = max(ans, num);
num = 1;
}
}
ans = max(ans, num);
return ans >= k;
}
int main()
{
pre();
while(~scanf("%d%d", &n, &k))
{
for(int i = 0; i < n; i ++ )
arr[i] = read();
Hash[0] = 0;
for(int i = 1; i <= n; i ++ )
Hash[i] = (Hash[i - 1] * base % mod + (ll)arr[i - 1]) % mod;
int l = 1, r = n, mid, ans;
while(r >= l)
{
mid = (l + r) >> 1;
if(judge(mid))
{
ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
printf("%d\n", ans);
}
return 0;
}
双哈希AC CODE
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 2e4 + 7;
const int mod = 100007;
const ll base = 233;
const ll base2 = 131;
int read()
{
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
ll p1[maxN], Hash[maxN], p2[maxN], Hash2[maxN];
void pre()
{
p1[0] = 1;
for(int i = 1; i <= 20000; i ++ ) p1[i] = p1[i - 1] * base % mod;
}
void pre2()
{
p2[0] = 1;
for(int i = 1; i <= 20000; i ++ ) p2[i] = p2[i - 1] * base2 % mod;
}
ll get_hash(int l, int r, ll *p, ll *g)
{
return (g[r] - g[l - 1] * p[r - l + 1] % mod + mod) % mod;
}
int n, k, arr[maxN];
bool judge(int x)
{
pair<ll, ll>pi[maxN];
int cnt = 0;
for(int i = 1; i <= n - x + 1; i ++ )
{
ll fir = get_hash(i, i + x - 1, p1, Hash);
ll sec = get_hash(i, i + x - 1, p2, Hash2);
pi[cnt ++ ] = make_pair(fir, sec);
}
sort(pi, pi + cnt);
pair<ll, ll> tar = pi[0];
int ans = 0, num = 1;
for(int i = 1; i < cnt; i ++ )
{
if(tar.first == pi[i].first && tar.second == pi[i].second)
num ++;
else
{
tar = pi[i];
ans = max(ans, num);
num = 1;
}
}
ans = max(ans, num);
return ans >= k;
}
int main()
{
pre(); pre2();
while(~scanf("%d%d", &n, &k))
{
for(int i = 0; i < n; i ++ )
arr[i] = read();
Hash[0] = 0;
for(int i = 1; i <= n; i ++ )
Hash[i] = (Hash[i - 1] * base % mod + arr[i - 1]) % mod;
Hash2[0] = 0;
for(int i = 1; i <= n; i ++ )
Hash2[i] = (Hash2[i - 1] * base2 % mod + arr[i - 1]) % mod;
int l = 1, r = n, mid, ans;
while(r >= l)
{
mid = (l + r) >> 1;
if(judge(mid))
{
ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
printf("%d\n", ans);
}
return 0;
}