自己歪歪的做法WA了好多发。
原题中每一秒都相当于
x1 = f1(x1)
x2 = f2(x2)
然后这是一个定义域和值域都在[0,m-1]的函数,显而易见其会形成一个环。
而且环长不超过m,所以实际上问题就分为了两部分:
1.x1变到a1,x2变到a2(h -> a的长度)
2.x1做循环,x2做循环直到同时为a1,a2。(a -> a的长度)
我们设第一步分别用了m1 s, m2 s,第二步用了 t1 s ,t2 s。
对于第一部分我们可以直接枚举吗,因为长度不超过m。
对于第二部分实际上是两个式子。
ans = △1 * t1 + m1
ans = △2 * t2 + m2
这个式子只需要枚举就行了。因为m1,m2最多相差不超过m,而在最优决策下△1或△2绝对值每变化1,m1,m2必然至少变化1,所以△最大为m
问题解决,注意各种特判,比如都没有t值,有一个有t值,无解的情况。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdlib> 5 6 #define LL long long 7 8 using namespace std; 9 10 LL m,ans; 11 12 LL gcd(LL a,LL b){ 13 if(!b) return a; 14 return gcd(b,a%b); 15 } 16 17 /* 18 since the f(x) be an fuction from a num x to y. 19 so it may be a cricle. 20 */ 21 22 void solve(LL &ansv,LL &sumv){ 23 LL h,a,x,y,ans=0; 24 scanf("%I64d%I64d%I64d%I64d",&h,&a,&x,&y); 25 for(int i=1;i<=m;i++){ 26 h=(h*x%m+y)%m; 27 if(h==a){ 28 ansv=(LL)i; //how many seconds it would take for us to arrive ‘a‘ from ‘h‘ 29 goto L; 30 } 31 } 32 puts("-1"); 33 exit(0); 34 L:h=a; 35 sumv=-1; 36 for(int i=1;i<=m;i++){ 37 h=(h*x%m+y)%m; //how many seconds it would take for us to arrive ‘a‘ from ‘a‘ 38 if(h==a){ 39 sumv=(LL)i; 40 return; 41 } 42 } 43 } 44 45 /* 46 a1 + k1*a2 = b1 + k2*b2 47 48 ans = a1 (mod a2) 49 ans = b1 (mod b2) 50 */ 51 52 int main(){ 53 scanf("%I64d",&m); 54 LL a1,a2,b1,b2; 55 solve(a1,a2); 56 solve(b1,b2); 57 if(a1==b1) ans=a1; 58 else if(a2==-1&&b2==-1){ 59 puts("-1"); 60 return 0; 61 } 62 else if(a2==-1&&a1>b1&&(a1-b1)%b2==0) ans=a1; 63 else if(b2==-1&&b1>a1&&(b1-a1)%a2==0) ans=b1; 64 else if(a2==-1||b2==-1){ 65 puts("-1"); 66 return 0; 67 } 68 else{ 69 LL k1; 70 for(k1=0;k1<=m;k1++) 71 if((a1+k1*a2-b1)%b2==0){ 72 ans=a1+k1*a2; 73 if(ans>=b1) break; 74 } 75 if(k1>m) ans=-1; 76 } 77 printf("%I64d\n",ans); 78 return 0; 79 }
时间: 2025-01-15 20:29:43