zoukankan      html  css  js  c++  java
  • codeforces 722F

    题目链接: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
    ", ans);
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    [问题说明]文章中的Javascript造成首页无法正常显示
    目前博客园程序存在的性能问题
    日志文件分析工具—AWStats在IIS中的配置步骤
    [公告]博客园管理团队新增成员wayfarer
    mass Framework class模块 v6
    mass Framework ecma模块
    python 批量修改文件后缀
    创建纯空Object
    我的模块加载系统 v7
    软件公司的两种管理方式
  • 原文地址:https://www.cnblogs.com/sagitta/p/5928333.html
Copyright © 2011-2022 走看看