zoukankan      html  css  js  c++  java
  • 2018牛客网暑假ACM多校训练赛(第十场)H Rikka with Ants 类欧几里德算法

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-H.html

    题目传送门 - https://www.nowcoder.com/acm/contest/148/H

    题意

      有两只蚂蚁在一个二维平面上走。一开始,他们都在点 $(1,0)$ 的位置。

      Rikka 布置了三条规定:

      1. 第一只蚂蚁不能走过直线 $y=cfrac{a}{b} x$ 。

      2. 第二只蚂蚁不能走过直线 $y=cfrac{c}{d} y$ 。

      3. 所有蚂蚁都不能走过直线 $y=0$ 。

      每一只蚂蚁的行走方式都是一样的,即:如果能往上走,那么向上;否则向右。

      问这两只蚂蚁走过的路径上有多少个整点是重合的,如果答案为 $infty$ ,输出 $-1$ 。

      多组数据,$Tleq 10^5,0leq a,b,c,d leq 10^9$ 。

    题解

    upd(2018-08-28): 无意中发现我之前那个 上界 的取值写错了,40多个阅读居然没人指出QAQ……

      首先,判掉无穷的情况:即斜率相同。

      然后,强制 $y=cfrac ab x$ 的斜率比 $y=cfrac cd x$ 大。(即,如果小了就交换)

      记 $f(x)=y_1=cfrac ab x,g(x)=y_2=cfrac cd x$ ,

      因此,对于一个点 $x$ ,必然有 $y_1>y_2$ 。于是,重合的整点中,横坐标为 $x$ 的点的 $y$ 坐标必然 $leq y_2$ 。又由于 $f(x-1)>g(x-1)$ ,所以,横坐标为 $x$ 的重合的整点的 $y$ 坐标必然 $geqleftlfloor cfrac{a(x-1)}{b} ight floor$ 。

      于是,答案就是:

    $$egin{eqnarray*}&sum_{x=0}^{infty} maxleft(0,leftlfloorcfrac{c(x+1)}{d} ight floor-leftlfloorcfrac{ax-b}{b} ight floor ight)\=&sum_{x=0}^{infty} maxleft(0,leftlfloorcfrac{c(x+1)}{d} ight floor-leftlfloorcfrac{ax}{b} ight floor+1 ight)end{eqnarray*}$$

      我们考虑取一个上界,来从公式中拿掉那个 $max$ 。

      我们考虑到:

      如果我们取尽量大的 $i$ ,使得

    $$cfrac {ai}{b} leq cfrac{c(i+1)}{d} +1$$

      则,对于 $x>i$,显然有:

    $$leftlfloorcfrac{c(x+1)}{d} ight floor-leftlfloorcfrac{ax}{b} ight floor+1leq 0$$

      相反,对于 $x<i$ ,有:

    $$leftlfloorcfrac{c(x+1)}{d} ight floor-leftlfloorcfrac{ax}{b} ight floor+1geq 0$$

      这两个容易证明。

      那么我们就可以解得上界为 $i=leftlfloor cfrac{(c+d)b}{ad-bc} ight floor$ ,于是,我们可以把原式写成:

    $$egin{eqnarray*}&&sum_{x=0}^{infty} maxleft(0,leftlfloorcfrac{c(x+1)}{d} ight floor-leftlfloorcfrac{ax-b}{b} ight floor ight)\&=&sum_{x=0}^{infty} maxleft(0,leftlfloorcfrac{c(x+1)}{d} ight floor-leftlfloorcfrac{ax}{b} ight floor+1 ight)\&=&sum_{x=0}^{i}left(leftlfloorcfrac{c(x+1)}{d} ight floor-leftlfloorcfrac{ax}{b} ight floor+1 ight)\&=&sum_{x=0}^{i}leftlfloorcfrac{c(x+1)}{d} ight floor-sum_{x=0}^{i}leftlfloorcfrac{ax}{b} ight floor +i+1end{eqnarray*}$$

      上面前两个 $sum$ 是裸的类欧,直接拖一份写就可以了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int mod=998244353;
    typedef long long LL;
    typedef __int128 LLL;
    LL f(LL a,LL b,LL c,LL n){
    	if (a==0)
    		return (b/c)%mod*((n+1)%mod)%mod;
    	if (a>=c||b>=c)
    		return ((LL)((LLL)a/c%mod*(n*(n+1)/2%mod))%mod
    					+(b/c)*(n+1)%mod+f(a%c,b%c,c,n))%mod;
    	LL tmp=((LLL)a*n+b)/c;
    	return (tmp%mod*n%mod-f(c,c-b-1,a,tmp-1)+mod)%mod;
    }
    LL T,a,b,c,d;
    void write(LLL x){
    	if (x<0){
    		putchar('-');
    		x=-x;
    	} 
    	if (x>9)
    		write(x/10);
    	putchar('0'+x%10);
    }
    LL calc(LL x){
    	return (f(c,c,d,x)-f(a,0,b,x)+x+1+mod)%mod;
    }
    int main(){
    	scanf("%lld",&T);
    	while (T--){
    		scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
    		if (a*d==b*c){
    			puts("-1");
    			continue;
    		}
    		if (a*d<b*c)
    			swap(a,c),swap(b,d);
    		printf("%lld
    ",calc((c+d)*b/(d*a-c*b)));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    scp命令报错-bash: scp: command not found
    shell比较两个字符串是否相等
    bat脚本:自动压缩n天前的文件【转载】
    shell bash判断文件或文件夹是否存在
    linux文件分割(将大的日志文件分割成小的)【转载】
    TCP/IP模型各个层次的功能和协议
    nginx初级安装配置
    Heartbeat+DRBD+MySQL高可用方案【转】
    【转载】CentOS 6.4下PXE+Kickstart无人值守安装操作系统
    oracle的exp和imp命令的使用【转载】
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-H.html
Copyright © 2011-2022 走看看