• Educational Codeforces Round 16 D&E.


    D. Two Arithmetic Progressions
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given two arithmetic progressions: a1k + b1 and a2l + b2. Find the number of integers x such that L ≤ x ≤ R and x = a1k' + b1 = a2l' + b2, for some integers k', l' ≥ 0.

    Input

    The only line contains six integers a1, b1, a2, b2, L, R (0 < a1, a2 ≤ 2·109,  - 2·109 ≤ b1, b2, L, R ≤ 2·109, L ≤ R).

    Output

    Print the desired number of integers x.

    Examples
    input
    2 0 3 3 5 21
    output
    3
    input
    2 4 3 0 6 17
    output
    2

    不要做这道有毒的题,这道题只有35个人做出来,E却有接近1k,可见这题有多恶心

    首先推一下式子

    $ x = a_{1}k+b_{1} = a_{2}l+b_{2} $

    $ a_{1}k-a_{2}l = b_{2} - b_{1} $

    拓展欧几里得解出一组k,l,然后就是求满足范围的k,l组数有多少个

    我们知道对于一组合法的k,l,$ k+t*a_{2}/gcd(a_{1},a_{2}), l+t*a_{1}/gcd(a_{1},a_{2}) $ 也是一组合法的解,于是我们可以二分一下t的合法范围

    同时由于k,l要大于0,这也对t提出了一个限制,同时处理一下这个范围,取个交集即可

    然后开始出问题

    1、long long会各种溢出,而且一开始算初始解的时候就会,解决方法:一开始算初始解的时候取一组小一点的解,中间一旦溢出就认为算出了无穷大,直接讨论判断合不合法(这个是不能严格证明正确性的)

    2、这个范围是一个不合法---合法---不合法的东西,二分不是很靠谱,解决方法:无视之,第二种限制只二分左端点

    交了大概15次

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <string>
      6 #include <cstring>
      7 #include <cmath>
      8 #include <map>
      9 #include <stack>
     10 #include <set>
     11 #include <vector>
     12 #include <queue>
     13 #include <time.h>
     14 #define eps 1e-7
     15 #define INF 0x3f3f3f3f
     16 #define LINF 0x3f3f3f3f3f3f3f3f
     17 #define MOD 1000000007
     18 #define rep0(j,n) for(int j=0;j<n;++j)
     19 #define rep1(j,n) for(int j=1;j<=n;++j)
     20 #define pb push_back
     21 #define set0(n) memset(n,0,sizeof(n))
     22 #define ll long long
     23 #define ull unsigned long long
     24 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
     25 #define print_runtime printf("Running time:%.3lfs
    ",double(clock())/1000.0)
     26 #define TO(j) printf(#j": %lld
    ",j)
     27 //#define OJ
     28 using namespace std;
     29 const int MAXINT = 100010;
     30 const int MAXNODE = 100010;
     31 const int MAXEDGE = 2 * MAXNODE;
     32 char BUF, *buf;
     33 int read() {
     34     char c = getchar(); int f = 1, x = 0;
     35     while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); }
     36     while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); }
     37     return f * x;
     38 }
     39 char get_ch() {
     40     char c = getchar();
     41     while (!isalpha(c)) c = getchar();
     42     return c;
     43 }
     44 //------------------- Head Files ----------------------//
     45 ll a1, b1, a2, b2, l, r;
     46 ll exgcd(ll a, ll b, ll &x, ll &y) {
     47     if (b == 0) {
     48         x = 1; y = 0;
     49         return a;
     50     }
     51     ll ret = exgcd(b, a % b, x, y);
     52     int t = x;
     53     x = y;
     54     y = t - a / b * y;
     55     return ret;
     56 }
     57 void get_input();
     58 void work();
     59 int main() {
     60     get_input();
     61     work();
     62     return 0;
     63 }
     64 void work() {
     65     ll x, y, c = b2 - b1, v, lb, rb, ansl, ansr, mid;
     66     ll gcd = exgcd(a1, a2, x, y);
     67     if (c%gcd != 0) { printf("0
    "); return; }
     68     ll lcm = a1*a2 / gcd;
     69     x *= c / gcd;
     70     ll t = x / (a2 / gcd);
     71     x %= a2 / gcd;
     72     y *= -c / gcd;
     73     y -= t* (a1 / gcd);
     74     //x=abs(x);y=abs(y);
     75     v = x*a1 + b1;
     76     /*TO(x);
     77     TO(y);
     78     TO(lcm);
     79     TO(v);*/
     80     lb = -INF * 5ll, rb = INF * 5ll;
     81     while (rb - lb>1) {
     82         mid = (lb + rb) / 2;
     83         if ((LINF / abs(lcm)>abs(mid) && v + mid*lcm >= l) || ((LINF / abs(lcm)<abs(mid)) && !((lcm>0) ^ (mid>0)))) rb = mid;
     84         else lb = mid;
     85     }
     86     ansl = rb;
     87     lb = -INF * 4ll, rb = INF * 4ll;
     88     while (rb - lb>1) {
     89         mid = (lb + rb) / 2;
     90         if (x + mid*a2 / gcd >= 0 && y + mid*a1 / gcd >= 0) rb = mid;
     91         else lb = mid;
     92     }
     93     ansl = max(ansl, rb);
     94     lb = -INF * 4ll, rb = INF * 4ll;
     95     while (rb - lb>1) {
     96         mid = (lb + rb) / 2;
     97         if ((LINF / abs(lcm)>abs(mid) && v + mid*lcm <= r) || (LINF / abs(lcm)<abs(mid) && ((lcm>0) ^ (mid>0)))) lb = mid;
     98         else rb = mid;
     99     }
    100     ansr = lb;
    101     lb = -INF * 4ll, rb = INF * 4ll;
    102     /*while (rb - lb>1) {
    103         mid = (lb + rb) / 2;
    104         if (x + mid*a2 / gcd >= 0 && y + mid*a1 / gcd >= 0) rb = mid;
    105         else rb = mid;
    106     }
    107     ansr = min(lb, ansr);*/
    108     //TO(ansl); TO(ansr);
    109     if (ansr<ansl) printf("0
    ");
    110     else printf("%lld
    ", ansr - ansl + 1);
    111 }
    112 void get_input() {
    113     a1 = read(); b1 = read(); a2 = read(); b2 = read(); l = read(); r = read();
    114 }
    少女抱B中
    E. Generate a String
    time limit per test
    2 seconds
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    zscoder wants to generate an input file for some programming competition problem.

    His input is a string consisting of n letters 'a'. He is too lazy to write a generator so he will manually generate the input in a text editor.

    Initially, the text editor is empty. It takes him x seconds to insert or delete a letter 'a' from the text file and y seconds to copy the contents of the entire text file, and duplicate it.

    zscoder wants to find the minimum amount of time needed for him to create the input file of exactly n letters 'a'. Help him to determine the amount of time needed to generate the input.

    Input

    The only line contains three integers nx and y (1 ≤ n ≤ 107, 1 ≤ x, y ≤ 109) — the number of letters 'a' in the input file and the parameters from the problem statement.

    Output

    Print the only integer t — the minimum amount of time needed to generate the input file.

    Examples
    input
    8 1 1
    output
    4
    input
    8 1 10
    output
    8

     DP方程是显然的,dp[i] = min(dp[i-1]+x,dp[i+1]+x,dp[i/2]+y(if i&1==0)  )

    然而这个dp没有一个合理的顺序,不能顺着推,当然可以用最短路的方法做,不过这个n=1e7会t

    观察一下,我们发现一个性质:任何时候不会有两个连续的删去字符,证明如下

    考虑最开始的两个连续的删去,显然他们不会是最开始的两个操作,我们思考它们前面可能是什么操作

    1、输入一个a,那么这显然不优,我们可以讲一次删除和一次输入一起消去

    2、复制一次,这显然不优,我们用c代表复制,d代表删除,显然有 cdd = dc,那么dc是更优的选择

    有了这个性质,我们可以发现一些有趣的事实:

    1、如果i是奇数,它只能是由i+1删去一个字符或者i-1添加一个字符得到(这很显然)

    2、如果i是偶数,那么不可能由i+1删去一个字符得到i,因为i+1只能是由i+2删去一个字符或者i添加一个字符得到,如果删去一个字符得到i是不符合我们上面的论断的

    那么我们可以有这样的dp方程

    i是奇数:dp[i] = min(dp[i-1]+x,dp[(i+1)/2]+x+y)

    i是偶数:dp[i] = min(dp[i-1]+x,dp[i/2]+y)

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <string>
     6 #include <cstring>
     7 #include <cmath>
     8 #include <map>
     9 #include <stack>
    10 #include <set>
    11 #include <vector>
    12 #include <queue>
    13 #include <time.h>
    14 #define eps 1e-7
    15 #define INF 0x3f3f3f3f
    16 #define MOD 1000000007
    17 #define rep0(j,n) for(int j=0;j<n;++j)
    18 #define rep1(j,n) for(int j=1;j<=n;++j)
    19 #define pb push_back
    20 #define set0(n) memset(n,0,sizeof(n))
    21 #define ll long long
    22 #define ull unsigned long long
    23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
    24 #define print_runtime printf("Running time:%.3lfs
    ",double(clock())/1000.0)
    25 #define TO(j) printf(#j": %d
    ",j);
    26 //#define OJ
    27 using namespace std;
    28 const int MAXINT = 10000010;
    29 const int MAXNODE = 100010;
    30 const int MAXEDGE = 2*MAXNODE;
    31 char BUF,*buf;
    32 int read(){
    33     char c=getchar();int f=1,x=0;
    34     while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    35     while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    36     return f*x;
    37 }
    38 char get_ch(){
    39     char c=getchar();
    40     while(!isalpha(c)) c=getchar();
    41     return c;
    42 }
    43 //------------------- Head Files ----------------------//
    44 
    45 ll n,x,y,dp[MAXINT];
    46 void get_input();
    47 void work();
    48 int main() {
    49     get_input();
    50     work();
    51     return 0;
    52 }
    53 void work(){
    54     dp[0]=0;
    55     for(int i=1;i<=n;i++){
    56         if(i&1){
    57             dp[i]=min(dp[i-1]+x,dp[(i+1)/2]+x+y);
    58         }else{
    59             dp[i]=min(dp[i-1]+x,dp[i/2]+y);
    60         }
    61     }
    62     printf("%lld
    ",dp[n]);
    63 }
    64 void get_input(){
    65     n=read();x=read();y=read();
    66 }
    少女祈祷中
  • 相关阅读:
    基本的Web控件二
    基本的Web控件一
    centos更改默认语言
    nginx优化配置
    使用nginx的proxy_cache做网站缓存
    centos7配置笔记
    redis批量删除
    Linq常用操作
    MVC ViewData和ViewBag[转]
    Transact-SQL的除法问题
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/7009089.html
Copyright © 2020-2023  润新知