Codeforces Round #305 (Div. 2) C. Mike and Frog
2015-05-30 11:04
274 查看
刚开始以为主要难在优化时间,结果发现其实难点在考虑周全……
首先用数组x和y保存下来h1与h2对m取余的数,并用t1、t2表示h1与h2的循环节长度,s1、s2表示首次取到a1、a2时的秒数。
当s1或s2为0时,即未从x、y中找到a1、a2,直接输出-1即可。
当s1与s2都找到后,由于部分h1与h2的数据不一定在循环节中,用x[h1]与y[h2]分别表示二者进入循环节之前的时间,先将二者较长的作为范围,从中寻找s1和s2。
若未找到,则判断s1与s2是否都未在循环节中,若都未在,则输出-1,否则进入循环节中寻找。
下面是代码
首先用数组x和y保存下来h1与h2对m取余的数,并用t1、t2表示h1与h2的循环节长度,s1、s2表示首次取到a1、a2时的秒数。
当s1或s2为0时,即未从x、y中找到a1、a2,直接输出-1即可。
当s1与s2都找到后,由于部分h1与h2的数据不一定在循环节中,用x[h1]与y[h2]分别表示二者进入循环节之前的时间,先将二者较长的作为范围,从中寻找s1和s2。
若未找到,则判断s1与s2是否都未在循环节中,若都未在,则输出-1,否则进入循环节中寻找。
下面是代码
#include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cstdlib> #include <string> #include <vector> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> using namespace std; int x[1000005],y[1000005]; int main() { long long m,i,a1,a2,x1,x2,y1,y2; long long h1,h2,t1,t2,h3,h4; while(cin>>m) { cin>>h1>>a1>>x1>>y1; cin>>h2>>a2>>x2>>y2; h3=h1,h4=h2; long long s1=0,s2=0; memset(x, 0, sizeof(x)); memset(y, 0, sizeof(y)); if(x[h1]==0) x[h1]=1; for(i=2;;i++) { h1=h1*x1+y1; h1%=m; if(x[h1]!=0) {t1=i-x[h1];break;} if(x[h1]==0) x[h1]=i; if(h1==a1) s1=i-1; } x[h1]-=1; if(y[h2]==0) y[h2]=1; for(i=2;;i++) { h2=h2*x2+y2; h2%=m; if(y[h2]!=0) {t2=i-y[h2];break;} if(y[h2]==0) y[h2]=i; if(h2==a2) s2=i-1; } y[h2]-=1; if(s1*s2==0) cout<<"-1"<<endl; else { { int flag=0; if(t2<t1) { swap(t2, t1); swap(s1, s2); } else if(t2==t1&&s2>s1) swap(s1, s2); { long long max1=max(x[h1],y[h2]); for (i=0; i<=t2+max1; i++) { if(i<max1) { h3=h3*x1+y1; h4=h4*x2+y2; h3%=m; h4%=m; if(h3==a1&&h4==a2) {cout<<i+1<<endl;flag=1;break;} continue; } if(s1<=x[h1]&&s2<=y[h2]) {cout<<"-1"<<endl;flag=1;break;} if(s1%t2==s2%t2) {cout<<s1<<endl;flag=1;break;} s1+=t1; } } if(!flag) cout<<"-1"<<endl; } } } return 0; }
相关文章推荐