zoukankan      html  css  js  c++  java
  • 【洛谷P3409】值日班长值周班长

    题目

    题目链接:https://www.luogu.com.cn/problem/P3409
    一开始读题了,一下所有 (m)(p) 与题目中意思对调。
    话说,在一个学期共有 (n) 个值日班长,其中 A 是第 (p) 个值日班长,共有 (m) 个值周班长,B 是第 (q) 个值周班长。假设不考虑假期及其他额外上课休假,以及重排值日班长值周班长,即永远每周上 5 天休息 2 天,且这个学期永远不会结束。请问这学期第几天会第一次遇上 A 是值日班长且 B 是值周班长,若永远不会输出 Orz mgh!!!。
    (n,mleq 10^9)

    思路

    被卡了 long long 调了好久最后看题解都是用了 int128 的。。。
    考虑设值日班长轮了 (x) 轮,值周班长轮了 (y) 轮,显然就是要求最小的非负整数解 (x,y) 满足:

    [nx+p=5(my+q)+k ]

    其中 (k) 是这周还有多少天结束,显然可以枚举。
    对于每一个枚举的 (k),直接把式子化成

    [nx-5my=5q+k-p ]

    直接解出 (x,y) 的最小非负整数解,答案即为 (nx+p)
    时间复杂度 (O(Tlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef __int128 ll;
    
    const ll Inf=9223372036854775807LL;
    ll ans,n,m,p,q;
    long long _,__,___,____;
    /*
    ll read()
    {
    	ll d=0; char ch=getchar();
    	while (!isdiigt(ch)) ch=getchar();
    	while (isdigit(ch)) d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d;
    }
    */
    void write(ll x)
    {
    	if (x>9) write(x/10);
    	putchar(x%10+48);
    }
    
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
    	if (!b) { x=1; y=0; return a; }
    	ll d=exgcd(b,a%b,x,y),t=x; x=y; y=t-a/b*y;
    	return d;
    }
    
    int main()
    {
    	while (scanf("%lld%lld%lld%lld",&_,&__,&___,&____)!=EOF)
    	{
    		n=_; p=__; m=___; q=____;  // 疯了
    		p--; q--; ans=-1;
    		for (ll k=0;k<=4;k++)
    		{
    			ll x,y,d=exgcd(n,5*m,x,y),l=(n*5*m)/d/n;
    			if ((5*q+k-p)%d) continue;
    			x=((5*q+k-p)/d*x%l+l)%l;
    			if (ans<0) ans=x*n+p+1;
    				else ans=min(ans,x*n+p+1);
    		}
    		if (ans>=0) write(ans);
    			else printf("Orz mgh!!!");
    		putchar(10);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Mysql数据库快速备份还原-mysqldump
    写给年轻人的交友和人脉建议
    令人担忧的趋势:科技崇拜与人文失落
    高情商的特征
    高情商与朋友圈
    数据库临时表空间设置
    oracle 临时表空间的增删改查
    语言表达能力写作能力决定一个人的发展和未来
    一个人如何从平庸到优秀,再到卓越?
    06.堆排序
  • 原文地址:https://www.cnblogs.com/stoorz/p/14486356.html
Copyright © 2011-2022 走看看