2017 icpc 沈阳 G - Infinite Fraction Path

题目大意:有n个点, 每个点有一个数字0 - 9, 第 i 个点只能到 第(i * i + 1)个点,问你在哪个点出发走n次构成的数字串最大。

思路:利用求后缀数组的倍增比较思想, 许多细节需要注意。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define fi first
 4 #define se second
 5 #define mk make_pair
 6 #define pii pair<int,int>
 7 #define piii pair<int, pair<int,int>>
 8 using namespace std;
 9 
10 const int N=2e5+7;
11 const int M=1e4+7;
12 const int inf=0x3f3f3f3f;
13 const LL INF=0x3f3f3f3f3f3f3f3f;
14 const int mod=1e9 + 7;
15 
16 int n, tot, a[N], nx[N][19], sa[N], t[N], t2[N], c[N], nxk[N], ans[N];
17 vector<int> prek[N];
18 void buildSa(int n, int m) {
19     int i, j, *x = t, *y = t2;
20     for(i = 0; i < m; i++) c[i] = 0;
21     for(i = 0; i < n; i++) c[x[i] = a[i]]++, nxk[i] = i;
22     for(i = 1; i < m; i++) c[i] += c[i - 1];
23     for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
24 
25     for(int k = 1; k <= n; k <<= 1) {
26         for(i = 0; i < n; i++) nxk[i] = nx[nxk[i]][0], prek[i].clear();
27         for(i = 0; i < n; i++) prek[nxk[i]].push_back(i);
28         int p = 0;
29         for(i = 0; i < n; i++) {
30             for(j = 0; j < prek[sa[i]].size(); j++)
31                 y[p++] = prek[sa[i]][j];
32         }
33         for(i = 0; i < m; i++) c[i] = 0;
34         for(i = 0; i < n; i++) c[x[y[i]]]++;
35         for(i = 1; i < m; i++) c[i] += c[i - 1];
36         for(i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
37         swap(x, y);
38         p = 1; x[sa[0]] = 0;
39         for(i = 1; i < n; i++) {
40             if(y[sa[i - 1]] == y[sa[i]] && y[nxk[sa[i - 1]]] == y[nxk[sa[i]]])
41                     x[sa[i]] = p - 1;
42             else x[sa[i]] = p++;
43         }
44         if(p >= n) break;
45         m = p;
46     }
47 }
48 int main() {
49     int T; scanf("%d", &T);
50     for(int cas = 1; cas <= T; cas++) {
51         scanf("%d", &n);
52         for(int i = 0; i < n; i++) {
53             scanf("%1d", &a[i]);
54         }
55 
56         for(int i = 0; i < n; i++) {
57             nx[i][0] =  (1ll * i * i + 1) % n;
58         }
59 
60         for(int j = 1; j < 19; j++) {
61             for(int i = 0; i < n; i++) {
62                 nx[i][j] = nx[nx[i][j - 1]][j - 1];
63             }
64         }
65         buildSa(n, 10);
66         tot = 0;
67         int now = sa[n - 1];
68         for(int i = 1; i <= n; i++) {
69             ans[tot++] = a[now];
70             now = nx[now][0];
71         }
72         printf("Case #%d: ", cas);
73         for(int i = 0; i < tot; i++)
74             printf("%d", ans[i]);
75         puts("");
76     }
77     return 0;
78 }
79 /*
80 */

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/8998528.html