• @51nod



    @description@

    小Y喜欢研究数论,并且喜欢提一些奇怪的问题。
    这天他找了三个两两互质的数a, b, c,以及另一个数m, 现在他希望找到三个(0, m)范围内的整数x, y, z,使得:

    [x^a + y^b mod m = z^c mod m ]

    原题传送门。

    @solution@

    这是什么神仙构造题。。。

    先不考虑模数。尝试构造一个满足 (x^a + y^b = z^c) 的解。

    注意到平凡情况下总有 (2^{n - 1} + 2^{n - 1} = 2^n),于是我们尝试往这边凑:

    [egin{cases} x = 2^p, y = 2^q, z = 2^r\ ap = bq = n - 1\ cr = n\ end{cases} ]

    如果再记 (p = bt, q = at),则可以得到不定方程 (cr = abt + 1)。用 exgcd 解出该方程即可。

    不过,当模数为 2^k 时,该方法构造出来的数有可能模意义下为 0。我们尝试特判。
    注意到此时有 ((2^{k-1})^a = 0 mod 2^k (a > 1))。可以分类讨论 a, b, c 哪些为 1,然后特殊构造方案。

    @accepted code@

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if( b == 0 ) {
    		x = 1, y = 0;
    		return a;
    	}
    	ll d = exgcd(b, a % b, y, x);
    	y -= a/b*x; return d;
    }
    
    int m;
    int pow_mod(int b, ll p) {
    	int ret = 1;
    	for(ll i=p;i;i>>=1,b=1LL*b*b%m)
    		if( i & 1 ) ret = 1LL*ret*b%m;
    	return ret;
    }
    void solve() {
    	int a, b, c; scanf("%d%d%d%d", &m, &a, &b, &c);
    	for(int i=2;i<=30;i++)
    		if( (1 << i) == m ) {
    			int mid = m / 2;
    			if( c == 1 )
    				printf("%d %d %d
    ", 1, 1, 2);
    			else if( b != 1 )
    				printf("%d %d %d
    ", 1, mid, 1);
    			else if( a != 1 )
    				printf("%d %d %d
    ", mid, 1, 1);
    			else printf("%d %d %d
    ", 2, m - 1, 1);
    			return ;
    		}
    	ll x, y, d = exgcd(c, -1LL*a*b, x, y);
    	
    	if( d < 0 ) x *= -1, y *= -1, d *= -1;
    	if( x < 0 ) {
    		ll p = (-x+1LL*a*b-1)/(1LL*a*b);
    		x += p*a*b, y += p*c;
    	}
    	if( y < 0 ) {
    		ll p = (-y+c-1)/c;
    		x += p*a*b, y += p*c;
    	}
    	
    	printf("%d %d %d
    ", pow_mod(2, b*y), pow_mod(2, a*y), pow_mod(2, x));
    }
    
    int main() {
    	int T; scanf("%d", &T);
    	while( T-- ) solve();
    } 
    

    @details@

    因为系数有负,所以 exgcd 可能解出来的是 ax + by = -1 的情况。注意把负数转成正数。

  • 相关阅读:
    Linux 安装JDK Tomcat MySQL(使用Mac远程访问)
    Linux 基础
    IntelliJ IDEA 新建项目
    Android Studio|IntelliJ IDEA 常用快捷键(Mac|Window)
    C 进制 类型说明符 位运算 char类型
    C 函数
    C 流程控制
    113路径总和II
    111.二叉树的最小深度
    110.平衡二叉树
  • 原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/12447052.html
Copyright © 2020-2023  润新知