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 }
时间: 2024-11-03 22:45:37

codeforces 722F - Cyclic Cipher的相关文章

codeforces E. Cyclic Components

题目链接如下:http://codeforces.com/contest/977/problem/E 题目大意是说: 给你一个无向图,让你寻找该图中能够形成的环有多少个. 试着分析一下,如果要形成环,那么每一个节点的特点是什么?会发现,每一个节点的度为2,所以思路就是,建立一个图,通过搜索,保存路径,判断每一个节点的度即可.困难的地方在于:如何建立图以及如何搜索 代码如下: 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int

Codeforces - 102222C - Caesar Cipher

https://codeforc.es/gym/102222/my 好像在哪里见过这个东西?字符的左右移还是小心,注意在mod26范围内. #include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { int x=0; int f=0; char c; do { c=getchar(); if(c=='-') f=1; } while(c<'0'||c>'9'); do

Codeforces 754E:Dasha and cyclic table

Codeforces 754E:Dasha and cyclic table 题目链接:http://codeforces.com/problemset/problem/754/E 题目大意:$A$矩阵($size(A)=n \times m$,仅含'a'-'z')在整个平面做周期延拓,问$B$矩阵($size(B)=r \times c$,包含'a'-'z'及'?','?'为通配符)在哪些位置能与$A$矩阵匹配.输出$n \times m$的01矩阵,1表示在该位置匹配. 枚举+bitset常

Codeforces 708A Letters Cyclic Shift

[题目链接] A. Letters Cyclic Shift time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output You are given a non-empty string s consisting of lowercase English letters. You have to pick exactly one non-e

Codeforces Problem 708A Letters Cyclic Shift

 题目链接: http://codeforces.com/problemset/problem/708/A 题目大意: 从字符串s中挑选出一个子串(非空),将该子串中的每个字母均替换成前一个字母,如'b'换成'a','c'换成'b',以此类推,特别的,'a'要换成'z',问经过一次转换之后,字典序最小的字符串s为多少.注意“exactly one non-empty substring”这就意味着全'a'串也要变,即字符串"aaa",替换其中的字母(会使得字典序比原来大),但又要使字典

Codeforces Round #110 (Div. 1) C Cipher

题目链接:Cipher 题意:有一个只含有小写字母的字符串,每次可以执行的操作有两种:1. s[i]变为字母序中前面的一个,s[i+1]变为字母序中后面的一个:2. s[i]变为字母序中后面的一个,s[i+1]变为字母序中前面的一个('a'字母序中前一个不存在,'z'字母序中后一个不存在).问可以编程多少种不同的字符串. 题解:把每个字母看作一个权值,每次操作权值不会发生变化,而且长度相同且权值相同的字符串是可以相互转化的.本题有多组询问,所以与处理出 dp[i][j] 表示长度为 i 的字符串

CodeForces 709C Letters Cyclic Shift

贪心. 肯定是两个$a$之间的那些字符都$-1$,没有$a$就全部$-1$.如果输入的串全是$a$,那么把最后一个$a$改成$z$. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #inc

CodeForces 709C Letters Cyclic Shift (水题)

题意:给定一个字符串,让你把它的一个子串字符都减1,使得总字符串字典序最小. 析:由于这个题是必须要有一个字串,所以你就要注意这个只有一个字符a的情况,其他的就从开始减 1,如果碰到a了就不减了,如果到最后一位了还没开始减, 就减最后一位. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <c

CodeForces 363B Fence

Fence Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 363B64-bit integer IO format: %I64d      Java class name: (Any) There is a fence in front of Polycarpus's home. The fence consists of n planks of