• [AHOI2007]密码箱


    [AHOI2007]密码箱


    (n=1)时无解,(x=0)时不成立。


    暴力:(O(n))

    (1)~(n)扫一遍。


    扩展欧几里得

    发现一下式子:(x^2≡1(mod n))

    移项得:(x^2+k*n≒1)

    于是运用扩展欧几里得求得一组解,进行判断即可。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #define all(x) x.begin(),x.end()
    using namespace std;
    
    typedef long long LL;
    
    vector <LL> ans;
    LL n;
    void exgcd(LL a, LL b, LL &x, LL &y)
    {
    	if(!b)
    	{
    		x = 1, y = 0;	
    		return;
    	}	
    	exgcd(b, a % b, y, x);
    	y -= (a / b) * x;
    	return;
    }
    
    int main()
    {
    	scanf("%lld", &n);
    	if(n == 1)
    	{
    		puts("None");
    		return 0;
    	}
    	LL res, y;
    	exgcd(1, n, res, y);
    	LL tmp = res;
    	ans.clear();
    	while(tmp < n * n)
    	{
    		if((LL)sqrt(tmp) * sqrt(tmp) == tmp) ans.push_back(sqrt(tmp));
    		tmp += n;
    	}
    	tmp = res;
    	while(tmp > 0)
    	{
    		tmp -= n;
    		if((LL)sqrt(tmp) * sqrt(tmp) == tmp) ans.push_back(sqrt(tmp));
    	}
    	sort(all(ans));
    	for(int i = 0; i < ans.size(); ++ i) printf("%d
    ", ans[i]);
    	return 0;
    } 
    

    扫描*枚举

    由上述思路:(x^2+k*n=1)可以换一个角度思考。

    =>((x+1)(x-1)=k*n)

    这个式子提示我们,(n)(x+1)(x-1)的因数,不妨设(n=a*b),需要满足:(x-1|a)(x+1|b)(x-1|b)(x+1|a)

    那么枚举(n)的因数,选最大的往上枚举(x),最后判断。

    另外,不开long long可能有意想不到的错误。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    typedef long long LL;
    
    LL n, cnt = 0, ans[100000];
    
    int main()
    {
    	scanf("%lld", &n);	
    	if(n == 1)
    	{
    		puts("None");
    		return 0;
    	}
    	ans[cnt ++] = 1;
    	LL MAXN = sqrt(n), b;
    	//Time Complexity: O(n^{0.5}ln(n)) 
    	for(LL a = 1; a <= MAXN; ++ a)	
    	{
    		if(n % a == 0)
    		{
    			b = n / a;//枚举 n 的两个因数 
    			for(LL x = b + 1; x <= n; x += b) //枚举x-1|a&x+1|b的情况 
    			{
    				if((x + 1) % a == 0) ans[cnt ++] = x; 
    			}
    			if(a == b) break;   
    			for(LL x = b - 1; x <= n; x += b) //枚举x-1|b&x+1|a的情况 
    			{
    				if((x - 1) % a == 0) ans[cnt ++] = x;
    			}
    		}
    	} 
    	sort(ans, ans + cnt);
    	cnt = unique(ans, ans + cnt) - ans; 
    	for(int i = 0; i < cnt; ++ i) printf("%lld
    ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    2021.10 好运气
    2021.9 抢购
    2021.8 全周期工程师
    2021.7 创业者
    2021.6 过年
    jenkins学习17
    httprunner 3.x学习18
    httprunner 3.x学习17
    python笔记57-@property源码解读与使用
    httprunner 3.x学习16
  • 原文地址:https://www.cnblogs.com/zach20040914/p/14127980.html
Copyright © 2020-2023  润新知