D. ConstructOR

比较奇怪的数学题叭...

要求一个xx使之和a,ba,b或后都能整除dd.

首先a,ba,bminsufzeromin_{sufzero}假如少于ddminsufzeromin_{sufzero}这种一定是不存在酱紫的xx的.

不妨假设dd后面有kk00,dd'为去掉那kk00的数.那么我a,ba,b同理也需要去掉kk00.

之后我们用x{x}a,b{a,b}前面全部变成1{1}.

假设n=230kn=2^{30-k}.

那么a,ba,b就可以合在一起考虑了,不妨设值为y=pn+n1y=p*n+n-1,要求yy%dd'00.

y=pn+ny'=p*n+n.就是相当于yy'%dd'等于11.

貌似用exgcdexgcd就好了.

而且方程是一定有解的,因为dd'是奇数,AA是只含质因子22的偶数,gcdgcd一定是11.

所以好神奇诶?

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=2e5+5;
const int M=2;

ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0){x=1;y=0;return a;}
    ll d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

void run()
{
	ll a,b,d;
	scanf("%lld%lld%lld",&a,&b,&d);
	int sufa=0,sufb=0,sufd=0;
	while(a%2==0)	a/=2,sufa++;
	while(b%2==0)	b/=2,sufb++;
	while(d%2==0)	d/=2,sufd++;
	if(min(sufa,sufb)<sufd)
	{
		puts("-1");
		return;
	}
	ll A=1,ss=1;
	for(int i=1;i<=30-sufd;i++)	A=A*2;
	for(int i=1;i<=30;i++)	ss=ss*2; 
	ll C=(d);
	ll B=((1-A)%d+d)%d;
	if(B%__gcd(A,C)!=0)
	{
		puts("-1");
		return ;
	}
	ll x,y;
	ll D=exgcd(A,C,x,y);
	ll s=C/D;
	x=B/D*x;
	x=(x%s+s)%s;
	x=x*ss;
	ss=1;
	for(int i=1;i<=30;i++)
	{
		if(i>sufd)	x+=ss;
		ss=ss*2;
	}
	printf("%lld\n",x);
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		run();
	}
	return 0;
}
全部评论

相关推荐

头像
11-09 17:30
门头沟学院 Java
TYUT太摆金星:我也是,好几个华为的社招找我了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务