zoukankan      html  css  js  c++  java
  • 1479 小Y的数论题

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

    Input
    第一行一个数代表数据组数T
    接下来T行每行四个整数m, a, b, c
    满足a, b, c两两互质
    1 <= T <= 100000
    1 <= a, b, c <= 10^9
    3 <= m <= 10^9
    Output
    对于每组数据,如果不存在x, y, z满足条件,则输出"Stupid xiaoy"(不含引号)
    否则输出一行三个数分别为x, y, z
    Input示例
    1
    100 1 1 1
    Output示例
    1 2 3

    思路:
    考虑构造形如2^kab+2^kab=2^(kab+1)的式子
    那么只要找到合理的k使得(kab + 1)能被c整除,就可以构造出满足条件的x y z


    kab+1=lc
    那么有
    lc−kab=1
    可以用扩展欧几里得解这个不定方程

    此时存在的唯一问题是,若m是2的次幂,那么取模之后结果可能是0
    这种情况可以特殊处理,例如:
    若a > 1,取x = m / 2, y = z = 1
    b > 1类似
    否则若c > 1, 取x = y = z = m / 2
    否则取x = y = 1, z = 2
    
    
     1 #include <stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<math.h>
     5 #include<algorithm>
     6 #include<iostream>
     7 using namespace std;
     8 typedef long long LL;
     9 pair<LL,LL>exgcd(LL n,LL m);
    10 LL quick(LL n,LL m,LL mod);
    11 int main(void)
    12 {
    13         LL m,a,b,c;
    14         LL x,y,z;
    15         int T;
    16         scanf("%d",&T);
    17         while(T--)
    18         {scanf("%lld %lld %lld %lld",&m,&a,&b,&c);
    19         if(m&(m-1))
    20         {
    21             pair<LL,LL>ask = exgcd(c,a*b);
    22             ask.second = -ask.second;
    23             while(ask.first<0||ask.second<0)
    24             {
    25                 ask.first+=a*b;
    26                 ask.second+=c;
    27             }
    28             x = quick((LL)2,ask.second*b,m);
    29             y = quick((LL)2,ask.second*a,m);
    30             z = quick((LL)2,ask.first,m);
    31         }
    32         else
    33         {       //printf("1
    ");
    34                 if(a > 1)
    35                 {
    36                         x = m/2;
    37                         y = 1;
    38                         z = 1;
    39                 }
    40                 else if(b>1)
    41                 {
    42                         x = 1;
    43                         y = m/2;
    44                         z = 1;
    45                 }
    46                 else if(c > 1)
    47                 {
    48                         x = m/2;
    49                         y = m/2;
    50                         z = m/2;
    51                 }
    52                 else
    53                 {
    54                         x = 1;
    55                         y = 1;
    56                         z = 2;
    57                 }
    58         }
    59         printf("%lld %lld %lld
    ",x,y,z);}
    60         return 0;
    61 }
    62 pair<LL,LL>exgcd(LL n,LL m)
    63 {
    64         if(m==0)
    65                 return make_pair(1,0);
    66         else
    67         {
    68                 pair<LL,LL>ak = exgcd(m,n%m);
    69                 return make_pair(ak.second,ak.first-(n/m)*ak.second);
    70         }
    71 }
    72 LL quick(LL n,LL m,LL mod)
    73 {
    74     LL ask = 1;
    75     while(m)
    76     {
    77         if(m&1)
    78             ask = ask*n%mod;
    79         n = n*n%mod;
    80         m/=2;
    81     }
    82     return ask;
    83 }
    
    

    代码库

    
    
  • 相关阅读:
    类的加载与ClassLoader的理解
    反射:获取Class 类的实例(四种方法)
    磁盘调度算法
    死锁检测算法
    银行家算法
    最低松弛度调度算法模拟
    多级反馈队列调度算法
    内存中:请求调页存储管理方式的模拟
    内存的动态分区分配方式的模拟
    “短进程优先”调度算法
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5950361.html
Copyright © 2011-2022 走看看