zoukankan      html  css  js  c++  java
  • CodeForces 710D

    洛谷题目页面传送门 & CodeForces题目页面传送门

    (2)个等差数列(A:A_i=a_1i+b_1(iinmathbb N),B:B_i=a_2i+b_2(iinmathbb N))。给定(l,r),求有多少个整数(nin[l,r])满足(n)既在(A)内又在(B)内。

    (a_1,a_2inleft(0,2 imes10^9 ight]capmathbb Z,b_1,b_2,l,rinleft[-2 imes10^9,2 imes10^9 ight]capmathbb Z,lleq r)

    (n)(A)中是第(xinmathbb N)项,在(B)中是第(yinmathbb N)项,则可以列出不定方程

    [a_1x+b_1=a_2y+b_2 ]

    转化成标准形式,得

    [a_1x-a_2y=b_2-b_1 ]

    这个显然可以用Exgcd先确定无解并输出(0)走人,或确定有解并得到一组特解(egin{cases}x=x'\y=y'end{cases})。令(Delta x=dfrac{a_2}{gcd(a_1,a_2)},Delta y=dfrac{a_1}{gcd(a_1,a_2)}),则通解是(egin{cases}x=x'+kDelta x\y=y'+kDelta yend{cases}(kinmathbb Z))。但对于(x,y)还有一个特殊的条件,就是(x,yinmathbb N)。不难发现(x,y)同增同减,不妨找到使得(x,y)都最小的一组解(egin{cases}x=x''\y=y''end{cases})(x,y)都最小,当且仅当(x-Delta x<0)(y-Delta y<0),于是分别令(x''=x'mod Delta x,y''=y'mod Delta y),每次带入原方程解出另一个变量看是否(geq0),必有一次合法。

    现在知道了(x'',y''),通解就变成了(egin{cases}x=x''+kDelta x\y=y''+kDelta yend{cases}(kin mathbb N))。将(x=x''+kDelta x)带入(a_1x+b_1in[l,r])

    [a_1(x''+kDelta x)+b_1in[l,r] ]

    [a_1x''+a_1kDelta x+b_1in[l,r] ]

    [a_1kDelta xin[l-a_1x''-b_1,r-a_1x''-b_1] ]

    [kinleft[dfrac{l-a_1x''-b_1}{a_1Delta x},dfrac{r-a_1x''-b_1}{a_1Delta x} ight] ]

    又因为(kinmathbb N),所以

    [kinleft[maxleft(0,leftlceildfrac{l-a_1x''-b_1}{a_1Delta x} ight ceil ight),leftlfloordfrac{r-a_1x''-b_1}{a_1Delta x} ight floor ight] ]

    然后算出(k_{min},k_{max})(max(0,k_{max}-k_{min}+1))就是答案。

    最后吐槽一下,C++中的/号是向零取整,也就是(<0)时上取整、(geq0)时下取整,(k)的解集中如果直接用/号算会WA,然后心态爆炸。所以必须要将被除数和除数统一取绝对值,然后利用(leftlfloordfrac ab ight floor+leftlceildfrac {-a}b ight ceil=0)这个原理计算,最后该取相反数取相反数:

    int quo_floor(int x,int y){return (x<0)^(y<0)?-(abs(x)+abs(y)-1)/abs(y):x/y;}
    int quo_ceil(int x,int y){return (x<0)^(y<0)?-abs(x)/abs(y):(x+y-1)/y;}
    

    下面贴AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int quo_floor(int x,int y){return (x<0)^(y<0)?-(abs(x)+abs(y)-1)/abs(y):x/y;}//下取整 
    int quo_ceil(int x,int y){return (x<0)^(y<0)?-abs(x)/abs(y):(x+y-1)/y;}//上取整 
    int exgcd(int a,int b,int &x,int &y){//Exgcd 
    	if(!b)return x=1,y=0,a;
    	int d=exgcd(b,a%b,y,x);
    	return y-=a/b*x,d;
    }
    int a1,a2,b1,b2,l,r;//题目给的参数 
    signed main(){
    	cin>>a1>>b1>>a2>>b2>>l>>r;
    	int x,y,gcd=exgcd(a1,-a2,x,y);
    	if((b2-b1)%gcd)return puts("0"),0;//无解 
    	x*=(b2-b1)/gcd;y*=(b2-b1)/gcd;//找到特解 
    	int dx=abs(a2/gcd),dy=abs(a1/gcd); 
    	((x%=dx)+=dx)%=dx;y=(a1*x-(b2-b1))/a2;
    	if(y<0)((y%=dy)+=dy)%=dy,x=(a2*y+(b2-b1))/a1;//找到使x,y都最小的解 
    	int l0=max(0ll,quo_ceil(l-a1*x-b1,a1*dx)),r0=quo_floor(r-a1*x-b1,a1*dx);//k[min],k[max] 
    	cout<<max(0ll,r0-l0+1);//答案 
    	return 0;
    }
    
  • 相关阅读:
    简述智障版本搜索引擎架构
    kaggle PredictingRedHatBusinessValue 简单的xgboost的交叉验证
    机器学习速查表
    World final 2017 题解
    微博爬虫
    喵哈哈村的魔法考试 Round #21 (Div.2) 题解
    喵哈哈村的魔法考试 Round #20 (Div.2) 题解
    Tinkoff Challenge
    常用的机器学习&数据挖掘知识(点)总结
    喵哈哈村的魔法考试 Round #19 (Div.2) 题解
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/CodeForces-710D.html
Copyright © 2011-2022 走看看