比赛 ZLXSCDay1 评测结果 AAWWWAAAAA
题目名称 多-有丝分裂 最终得分 70
用户昵称 Zayin 运行时间 2.670 s
代码语言 C++ 内存使用 15.57 MiB
提交时间 2016-03-18 20:57:29
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL __LL64
#define N 1000000
using namespace std;
typedef long long LL;
struct Node{
	LL idx;
	LL val;
}baby[N];
bool cmp(Node n1,Node n2){
	return n1.val!=n2.val?n1.val<n2.val:n1.idx<n2.idx;
}
LL gcd(LL a,LL b){
	return b==0?a:gcd(b,a%b);
}
LL extend_gcd(LL a,LL b,LL &x,LL &y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	LL gcd=extend_gcd(b,a%b,x,y);
	LL t=x;
	x=y;
	y=t-a/b*y;
	return gcd;
}
LL inval(LL a,LL b,LL n){
	LL e,x,y;
	extend_gcd(a,n,x,y);
	e=((LL)x*b)%n;
	return e<0?e+n:e;
}
LL PowMod(LL a,LL b,LL MOD){
	LL ret=1%MOD,t=a%MOD;
	while(b){
		if(b&1)
			ret=((LL)ret*t)%MOD;
		t=((LL)t*t)%MOD;
		b>>=1;
	}
	return (LL)ret;
}
LL BinSearch(LL num,LL m){
	LL low=0,high=m-1,mid;
	while(low<=high){
		mid=(low+high)>>1;
		if(baby[mid].val==num)
			return baby[mid].idx;
		if(baby[mid].val<num)
			low=mid+1;
		else
			high=mid-1;
	}
	return -1;
}
LL BabyStep(LL A,LL B,LL C){
	LL tmp,D=1%C;
	LL temp;
	for(LL i=0,tmp=1%C;i<100;i++,tmp=((LL)tmp*A)%C)
		if(tmp==B)
			return i;
	LL d=0;
	while((temp=gcd(A,C))!=1){
		if(B%temp) return -1;
		d++;
		C/=temp;
		B/=temp;
		D=((A/temp)*D)%C;
	}
	LL m=(LL)ceil(sqrt((double)C));
	for(LL i=0,tmp=1%C;i<=m;i++,tmp=((LL)tmp*A)%C){
		baby[i].idx=i;
		baby[i].val=tmp;
	}
	sort(baby,baby+m+1,cmp);
	LL cnt=1;
	for(LL i=1;i<=m;i++)
		if(baby[i].val!=baby[cnt-1].val)
			baby[cnt++]=baby[i];
	LL am=PowMod(A,m,C);
	for(LL i=0;i<=m;i++,D=((LL)(D*am))%C){
		LL tmp=inval(D,B,C);
		if(tmp>=0){
			LL pos=BinSearch(tmp,cnt);
			if(pos!=-1)
				return i*m+pos+d;
		}
	}
	return -1;
}
int main(){
	freopen("mitotic_division.in","r",stdin);
	freopen("mitotic_division.out","w",stdout);
	LL T,A,B,C;
	cin>>T;
	while(T--){
		scanf("%lld%lld%lld",&A,&B,&C);
//		cout<<A<<" "<<B<<" "<<C<<endl;
		{
			LL ans,sum=1;
			for (ans=1;ans<=1000000;++ans)
			{
				sum=(sum*A) % C;
//				cout<<ans<<" "<<sum<<" "<<B<<endl;
				if (sum==B)
				{
					printf("%lld\n",ans);
					break;
				}
			}
			if (ans<=1000000) 
				continue;
		}
		if (B==1)
		{
			if (gcd(A,C)!=1)
			{
				printf("no solution\n");
				continue;
			}
			LL ans=C;
			for (LL i=2;i*i<=C;++i)
			{
				if (C%i)
				{
					for (;C%i==0;C/=i) ;
					ans=ans*(i-1)/i;
				}
			}
			printf("%d\n",ans);
		} else
		{
			LL ans=BabyStep(A,B,C);
			if(ans==-1)
				puts("no solution\n");
			else
				printf("%d\n",ans);
		}
	}
	return 0;
}