我们只要暴力枚举块的大小就可以了。。。

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

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

 

 1 /**************************************************************
 2     Problem: 2081
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:4932 ms
 7     Memory:18312 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12 #include <set>
13 #include <vector>
14  
15 using namespace std;
16 typedef unsigned long long ull;
17 const int N = 5e5 + 5;
18 const int base = 200191;
19  
20 int n, a[N], ans;
21 ull b[N], h1[N], h2[N];
22 vector <int> Ans;
23 vector <int> ::iterator it;
24  
25 inline int read() {
26     int x = 0, sgn = 1;
27     char ch = getchar();
28     while (ch < '0' || '9' < ch) {
29         if (ch == '-') sgn = -1;
30         ch = getchar();
31     }
32     while ('0' <= ch && ch <= '9') {
33         x = x * 10 + ch - '0';
34         ch = getchar();
35     }
36     return sgn * x;
37 }
38  
39 ull calc1(int l, int r) {
40     return h1[r] - h1[l - 1] * b[r - l + 1];
41 }
42  
43 ull calc2(int l, int r) {
44     return h2[l] - h2[r + 1] * b[r - l + 1];
45 }
46  
47 set <ull> S;
48 int calc(int sz) {
49     S.clear();
50     for (int i = 1; i + sz - 1 <= n; i += sz)
51         S.insert(min(calc1(i, i + sz - 1), calc2(i, i + sz - 1)));
52     return (int) S.size();
53 }
54  
55 int main() {
56     int i, t;
57     n = read();
58     for (i = 1; i <= n; ++i) a[i] = read();
59     for (i = b[0] = 1; i <= n; ++i) b[i] = b[i - 1] * base;
60     for (i = 1; i <= n; ++i)
61         h1[i] = h1[i - 1] * base + a[i];
62     for (i = n; i; --i)
63         h2[i] = h2[i + 1] * base + a[i];
64     ans = 0;
65     for (i = 1; i <= n; ++i) {
66         t = calc(i);
67         if (t > ans) {
68             ans = t;
69             Ans.clear();
70         }
71         if (ans == t) Ans.push_back(i);
72     }
73     printf("%d %d\n", ans, (int) Ans.size());
74     for (it = Ans.begin(); it != Ans.end(); ) {
75         printf("%d", *it), ++it;
76         if (it == Ans.end()) puts("");
77         else putchar(' ');
78     }
79     return 0;
80 }
View Code

 

posted on 2015-03-10 22:00  Xs酱~  阅读(471)  评论(0编辑  收藏  举报