codeforces 722F - Cyclic Cipher
Posted sagitta
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 722F - Cyclic Cipher相关的知识,希望对你有一定的参考价值。
题目链接:http://codeforces.com/problemset/problem/722/F
------------------------------------------------------------------------------
首先根据 $k <= 40$ 以及 $lcm(1...40)$ 在$long long$以内
可以意识到这题可以转化为求最大合法区间使得区间内的同余方程组合法
这个可以考虑用$exgcd$来做 并且也满足区间可合并的性质
对于一段连续区间 我们枚举左端点要找到最远的合法的右端点 可以先用$ST$表预处理后倍增查找
$($注意线段树/$ST$表要进行二分的时候不要真的进行二分 这样会多一个$log$ 要利用已经分割好的区间$)$
最后复杂度是$O(n * logn * exgcd$复杂度$)$
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 }
以上是关于codeforces 722F - Cyclic Cipher的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 754E:Dasha and cyclic table
Codeforce 977E Cyclic Components
codeforces E. Cyclic Components
CodeForces 709C Letters Cyclic Shift