您的位置:首页 > 其它

BZOJ2081 [Poi2010]Beads

2015-03-10 22:00 162 查看
我们只要暴力枚举块的大小就可以了。。。

枚举的总复杂度是O(n / 1 + n / 2 + n / 3 + ...) = O(n * logn)的

何如去重呢。。。直接暴力hash再丢进set里搞定,总复杂度O(n * log2n)

/**************************************************************
Problem: 2081
User: rausen
Language: C++
Result: Accepted
Time:4932 ms
Memory:18312 kb
****************************************************************/

#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;
typedef unsigned long long ull;
const int N = 5e5 + 5;
const int base = 200191;

int n, a
, ans;
ull b
, h1
, h2
;
vector <int> Ans;
vector <int> ::iterator it;

inline int read() {
int x = 0, sgn = 1;
char ch = getchar();
while (ch < '0' || '9' < ch) {
if (ch == '-') sgn = -1;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return sgn * x;
}

ull calc1(int l, int r) {
return h1[r] - h1[l - 1] * b[r - l + 1];
}

ull calc2(int l, int r) {
return h2[l] - h2[r + 1] * b[r - l + 1];
}

set <ull> S;
int calc(int sz) {
S.clear();
for (int i = 1; i + sz - 1 <= n; i += sz)
S.insert(min(calc1(i, i + sz - 1), calc2(i, i + sz - 1)));
return (int) S.size();
}

int main() {
int i, t;
n = read();
for (i = 1; i <= n; ++i) a[i] = read();
for (i = b[0] = 1; i <= n; ++i) b[i] = b[i - 1] * base;
for (i = 1; i <= n; ++i)
h1[i] = h1[i - 1] * base + a[i];
for (i = n; i; --i)
h2[i] = h2[i + 1] * base + a[i];
ans = 0;
for (i = 1; i <= n; ++i) {
t = calc(i);
if (t > ans) {
ans = t;
Ans.clear();
}
if (ans == t) Ans.push_back(i);
}
printf("%d %d\n", ans, (int) Ans.size());
for (it = Ans.begin(); it != Ans.end(); ) {
printf("%d", *it), ++it;
if (it == Ans.end()) puts("");
else putchar(' ');
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: