zoukankan      html  css  js  c++  java
  • [Educational Codeforces Round 16]D. Two Arithmetic Progressions

    [Educational Codeforces Round 16]D. Two Arithmetic Progressions

    试题描述

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

    输入

    The first line contains integer n (1 ≤ n ≤ 3·105) — the number of points on the line.

    The second line contains n integers xi ( - 109 ≤ xi ≤ 109) — the coordinates of the given n points.

    输出

    Print the only integer x — the position of the optimal point on the line. If there are several optimal points print the position of the leftmost one. It is guaranteed that the answer is always the integer.

    输入示例

    2 0 3 3 5 21

    输出示例

    3

    数据规模及约定

    解一下不定方程 a1k + b1a2l + b2,设 k mod lcm(a1, a2) / a1 的值是 t,设 lcm(a1, a2) / a1 = A,那么 k 可以写成 q·A + t 这个样子,那么显然 A 是有上下界的,我们二分到这个上下界,做个差就是答案了。

    一上午就调它了。。。woc cf 数据太强了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    #define MAXN 1000+10
    
    #define oo 4000000000ll
    #define LL long long
    #define LD long double
    LL a1, b1, a2, b2, L, R;
    
    LL gcd(LL a, LL b, LL& x, LL& y) {
    	if(b == 0){ x = 1, y = 0; return a; }
    	LL d = gcd(b, a % b, y, x); y -= (a / b) * x;
    	return d;
    }
    
    LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a % b); }
    
    int main() {
    	cin >> a1 >> b1 >> a2 >> b2 >> L >> R;
    	
    	LL k, t;
    	LL d = gcd(a1, a2, k, t);
    	if((b2 - b1) % d != 0) return puts("0"), 0;
    	k *= (b2 - b1) / d; t *= (b2 - b1) / d;
    	LL A2 = a2 / gcd(a1, a2);
    	LL mod = (k % A2 + A2) % A2, al, ar;
    //	printf("%lld %lld
    ", k, mod);
    	LL l, r; l = -oo - 1; r = oo + 1;
    //	printf("%lld %lld
    ", l, r);
    	while(l < r) {
    		LL mid = l + (r - l) / 2;
    		LL lsid = (L - b1) % a1 != 0 ? (L - b1) / a1 + (L - b1 > 0 ? 1 : 0) : (L - b1) / a1,
    		   rsid = (R - b1) % a1 != 0 ? (R - b1) / a1 + (R - b1 > 0 ? 0 : -1) : (R - b1) / a1,
    		   x = mid * A2 + mod;
    		LL l2 = (L - b2) % a2 != 0 ? (L - b2) / a2 + (L - b2 > 0 ? 1 : 0) : (L - b2) / a2,
    		   r2 = (R - b2) % a2 != 0 ? (R - b2) / a2 + (R - b2 > 0 ? 0 : -1) : (R - b2) / a2,
    		   y = ((LD)a1 * x - b2 + b1) / a2;
    //		printf("%lld %lld %lld %lld %lld [%lld, %lld]
    ", lsid, l2, mid, y, x, l, r);
    		if(lsid <= x && l2 <= y && x >= 0 && y >= 0) r = mid;
    		else l = mid + 1;
    	}
    	al = l;
    	l = -oo - 1; r = oo + 1;
    //	printf("%lld %lld
    ", l, r);1 -2000000000 2 2000000000 -2000000000 2000000000
    	while(l < r - 1) {
    		LL mid = l + (r - l) / 2;
    		LL lsid = (L - b1) % a1 != 0 ? (L - b1) / a1 + (L - b1 > 0 ? 1 : 0) : (L - b1) / a1,
    		   rsid = (R - b1) % a1 != 0 ? (R - b1) / a1 + (R - b1 > 0 ? 0 : -1) : (R - b1) / a1,
    		   x = mid * A2 + mod;
    		LL l2 = (L - b2) % a2 != 0 ? (L - b2) / a2 + (L - b2 > 0 ? 1 : 0) : (L - b2) / a2,
    		   r2 = (R - b2) % a2 != 0 ? (R - b2) / a2 + (R - b2 > 0 ? 0 : -1) : (R - b2) / a2,
    		   y = ((LD)a1 * x - b2 + b1) / a2;
    //		printf("%lld %lld %lld %lld %lld [%lld, %lld]
    ", mid, x, y, rsid, r2, l, r);
    		if(x <= rsid && y <= r2) l = mid;
    		else r = mid;
    	}
    	ar = l;
    //	printf("%lld %lld
    ", al, ar);
    	
    	LL mid = l + (r - l) / 2;
    	LL lsid = (L - b1) % a1 != 0 ? (L - b1) / a1 + (L - b1 > 0 ? 1 : 0) : (L - b1) / a1,
    	   rsid = (R - b1) % a1 != 0 ? (R - b1) / a1 + (R - b1 > 0 ? 0 : -1) : (R - b1) / a1,
    	   x = mid * A2 + mod;
    	LL l2 = (L - b2) % a2 != 0 ? (L - b2) / a2 + (L - b2 > 0 ? 1 : 0) : (L - b2) / a2,
    	   r2 = (R - b2) % a2 != 0 ? (R - b2) / a2 + (R - b2 > 0 ? 0 : -1) : (R - b2) / a2,
    	   y = ((LD)a1 * x - b2 + b1) / a2;
    	if(lsid <= x && x <= rsid && l2 <= y && y <= r2 && x >= 0 && y >= 0 && al <= ar)
    		cout << ar - al + 1 << endl;
    	else puts("0");
    	
    	return 0;
    }
    
  • 相关阅读:
    DevC++实现调试功能
    DevC++实现调试功能
    《算法竞赛入门经典》计算组合数问题
    C#根据控件名获取控件对象
    C#根据控件名获取控件对象
    C# 使用反射获取私有属性的方法
    C# 使用反射获取私有属性的方法
    JSON转Object的方式
    JSON转Object的方式
    Hadoop: Setting up a Single Node Cluster.
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5806786.html
Copyright © 2011-2022 走看看