例10-2 Disgruntled Judge (拓展GCD )存个模板

题目链接

解法: 枚举A的值[0, 10000](因为地推公式按10001取模, 如果大于10000就会重复之前的现象。比如:0和10001,用递推公式推出来的值都是一样的)。因为:

        
         整理为:
            

从而将问题转换为扩展欧几里得算法的问题(扩展欧几里得算法戳我),求出b,然后根据递推公式判断是否符合原来的数列,如果不符合说明不是这个数列的解。

转自:https://blog.csdn.net/CPOHUI/article/details/79933389

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
ll x[100005];

void ex_gcd(ll a , ll b ,ll &d, ll &x,ll &y){
	//d为gcd(a,b)
    if(!b){
        d = a ;
        x = 1;  y = 0;
        return ;
    }    
    ex_gcd(b , a % b ,d , y , x);
    y -= x * (a / b);
    return ;    
}
int main()
{
	scanf("%d",&n);
	for(int i=1,j=0;j<n;i+=2,j++)
	{
		scanf("%lld",&x[i]);
	}
	int mod=10001;
	ll a,b,k; 
	for(int i=1;i<=10000;i++)
	{
		b,a=i,k;
		
		//
		ll A=a+1,B=10001,C=1ll*x[3]-a*a*x[1]; 	
		ll GCD,x0,y0;	
		ex_gcd(a+1,-10001,GCD,x0,y0) ;
		if(C%GCD) continue; //无解 
		b=x0=x0/GCD*C;
		//ex_gcd 使用模块 
		 		
		int flag=0;
		for(int j=2;j<=2*n;j++)
		{
			ll xj=(x[j-1]*a+b+mod)%mod;			
			if(j%2)
			{
				if(xj==x[j])
				{
					if(j==2*n-1) flag=1;
					continue;
				}
				else break;
			}			
			x[j]=xj;
		}		
		if(flag) break;		
	}
	for(int i=2;i<=2*n;i+=2)
	{	
		printf("%d\n",x[i]);
	}
}

//3
//17
//822
//3014
发布了45 篇原创文章 · 获赞 6 · 访问量 1771

猜你喜欢

转载自blog.csdn.net/qq_43868883/article/details/104252574