# codeforces 722F - Cyclic Cipher

------------------------------------------------------------------------------

$($注意线段树/$ST$表要进行二分的时候不要真的进行二分 这样会多一个$log$ 要利用已经分割好的区间$)$

  1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N = 1e5 + 10, E = 2e5 + 10;
4 int len[N], firste[N], nexte[E], v[E], w[E];
5 int n, lim, e, ans, m;
6 void build(int x, int y, int z)
7 {
8     nexte[++e] = firste[x];
9     firste[x] = e;
10     v[e] = y;
11     w[e] = z;
12 }
13 void exgcd(long long a,long long b,long long &d, long long &x, long long &y)
14 {
15     if(!b)
16     {
17         x = 1;
18         y = 0;
19         d = a;
20     }
21     else
22     {
23         exgcd(b, a % b, d, y, x);
24         y -= x * (a / b);
25     }
26 }
27 long long a[17][N], b[17][N];
28 long long mul(long long aa, long long bb, long long mod)
29 {
30     return (aa * bb - (long long)(aa / (long double) mod * bb + 1e-3) * mod + mod) % mod ;
31 }
32 void solve(long long m1, long long b1, long long m2, long long b2, long long &m0, long long &b0)
33 {
34     if(m1 == -1 || m2 == -1)
35     {
36         m0 = b0 = -1;
37         return;
38     }
39     long long d, x, y;
40     exgcd(m1, m2, d, x, y);
41     if((b2 - b1) % d != 0)
42         m0 = b0 = -1;
43     else
44     {
45         long long t = m2 / d;
46         //x = (x % t * ((b2 - b1) / d % t) % t + t) % t;
47         x = (mul(x, (b2 - b1) / d, t) + t) % t;
48         m0 = m1 * (m2 / d);
49         b0 = m1 * x + b1;
50     }
51 }
52 int main()
53 {
54     scanf("%d%d", &n, &lim);
55     int x;
56     for(int i = 1; i <= n; ++i)
57     {
58         scanf("%d", &len[i]);
59         for(int j = 0; j < len[i]; ++j)
60         {
61             scanf("%d", &x);
62             build(x, i, j);
63         }
64     }
65     int last;
66     for(int u = 1; u <= lim; ++u)
67     {
68         ans = m = last = 0;
69         for(int p = firste[u]; ; p = nexte[p])
70         {
71             if(p && (!m || v[p] == last - 1))
72             {
73                 ++m;
74                 a[0][m] = len[v[p]];
75                 b[0][m] = w[p];
76                 last = v[p];
77                 continue;
78             }
79             else
80             {
81                 if(m > ans)
82                 {
83                     int top = 0;
84                     for(int i = 1; (1 << i) <= m; ++i)
85                     {
86                         top = i;
87                         for(int j = 1; j + (1 << i) - 1 <= m; ++j)
88                             solve(a[i - 1][j], b[i - 1][j], a[i - 1][j + (1 << (i - 1))],
89                             b[i - 1][j + (1 << (i - 1))], a[i][j], b[i][j]);
90                     }
91                     for(int j = 1; m - j + 1 > ans; ++j)
92                     {
93                         int k = j + 1;
94                         long long nowa = a[0][j], nowb = b[0][j], tmpa, tmpb;
95                         for(int i = top; i >= 0; --i)
96                             if(k + (1 << i) - 1 <= m)
97                             {
98                                 solve(nowa, nowb, a[i][k], b[i][k], tmpa, tmpb);
99                                 if(tmpa != -1)
100                                 {
101                                     k += (1 << i);
102                                     nowa = tmpa;
103                                     nowb = tmpb;
104                                 }
105                             }
106                         ans = max(ans, k - j);
107                     }
108                 }
109                 if(!p)
110                     break;
111                 m = 1;
112                 a[0][m] = len[v[p]];
113                 b[0][m] = w[p];
114                 last = v[p];
115             }
116         }
117         printf("%d\n", ans);
118     }
119     return 0;
120 }

posted @ 2016-10-02 23:02 sagitta 阅读(...) 评论(...) 编辑 收藏