挺简单的题目,但是有一堆恶心的边界
在刨去恶心的边界之后:
假定我们知道两边的循环节为b1,b2
其中h第一次到达目标的时间为a1,a2
又知道对于答案t
t=a1+b1*t1=a2+b2*t2
不妨枚举t1,判断是否存在可行解即可
又因为LCM(b1,b2)就开始循环了
且b1*b2<=b1*mod
所以我们枚举t1的范围在[0,mod]即可
如果在这个范围内无解,则一定无解
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; bool vis[1000010]; int mod,h,a,x,y; int Go(int h,int x,int y){ memset(vis,0,sizeof(vis)); int cnt=0; while(1){ if(vis[h])return -1; vis[h]=1; h=(1LL*h*x+y)%mod; ++cnt; if(h==a)return cnt; } } int main(){ scanf("%d",&mod); scanf("%d%d%d%d",&h,&a,&x,&y); int a1=Go(h,x,y),b1=Go(a,x,y); scanf("%d%d%d%d",&h,&a,&x,&y); int a2=Go(h,x,y),b2=Go(a,x,y); if(a1==-1||a2==-1){printf("-1\n");return 0;} if(b1==-1&&b2==-1){ if(a1==a2)printf("%d\n",a1); else printf("-1\n"); return 0; } if(b1!=-1&&b2!=-1){ for(int i=0;i<=mod;++i){ if(a1+1LL*b1*i>=a2&&(a1+1LL*b1*i-a2)%b2==0){ cout<<a1+1LL*b1*i<<endl; return 0; } }printf("-1\n"); return 0; }else{ if(b1==-1)swap(a1,a2),swap(b1,b2); if(a2>=a1&&(a2-a1)%b1==0)printf("%d\n",a2); else printf("-1\n"); }return 0; }
时间: 2024-12-25 23:15:21