zoukankan      html  css  js  c++  java
  • 欧几里德算法

    上次做2017 apac test 最后一轮的时候,第三题需要使用扩展欧几里德算法来求解方程的解的个数,刚好学习一下这个算法。上次学了一下,忘记记录下来,这次在做hr的题目的时候,有需要这个算法,还是不熟练,这里还是把上次的代码,先贴出来吧,需要的进行研究!

      1 #include<bits/stdc++.h>
      2 #define pb push_back
      3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i)
      4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl
      5 typedef long long ll;
      6 using namespace std;
      7 typedef pair<int, int> pii;
      8 const int maxn = 1e3 + 10;
      9 int a, b;
     10 int gcd(int x, int y) {
     11     if(y == 0) return x;
     12     return gcd(y, x % y);
     13 }
     14 int gcd2(int x, int y) {
     15     while(y != 0) {
     16         int t = x % y;
     17         x = y;
     18         y = t;
     19     }
     20     return x;
     21 }
     22 int exgcd(int a, int b, int &x, int &y) {
     23     if(b == 0) {
     24         x = 1;
     25         y = 0;
     26         return a;
     27     }
     28     int r = exgcd(b, a % b, x, y);
     29     int t = x;
     30     x = y;
     31     y = t - a / b * y;
     32     return r;
     33 }
     34 int work(int a, int b, int c) {
     35     int x, y;
     36     ll t = exgcd(a, b, x, y);
     37     //cout << t << " " << x << " " << y << endl;
     38     if(c % t != 0) return 0;
     39     ll f = c / t;
     40     //double z1 = 1.0 * -x * f * t / b;
     41     //double z2 = 1.0 * y * f * t / a;
     42     //int x1 = z1, x2 = z2;
     43     ll t1 = floor(1.0 * -x * f * t / b);
     44     ll t2 = floor(1.0 * y * f * t / a);
     45     //cerr << z1 << " " << x1 << " " << t1 << " " << z2 << " " << x2 << " " << t2 << endl;
     46     if(1ll * y * f * t % a == 0) t2--;
     47     return t2 - t1 < 0 ? 0 : t2 - t1;
     48 }
     49 /*
     50 cin >> a >> b;
     51     cout << __gcd(a, b) << endl;
     52     cout << gcd(a, b) << " " << gcd2(a, b) << endl;
     53     int x, y;
     54     int t = exgcd(a, b, x, y);
     55     cout << t << " " << x << " " << y << endl;
     56 */
     57 void extgcd(ll a,ll b,ll& d,ll& x,ll& y){
     58     if(!b){
     59         d=a;x=1;y=0;
     60     }else{
     61         extgcd(b,a%b,d,y,x);
     62         y-=x*(a/b);
     63     }
     64 }
     65 
     66 int work1(int a,int b,int n){
     67     if(n%__gcd(a,b)!=0)return 0;
     68     ll g,p0,q0;
     69     extgcd(a,b,g,p0,q0);
     70     p0*=n/g;q0*=n/g;
     71     int less=floor((-p0)*g*1.0/b),great=floor(q0*g*1.0/a);
     72     if(q0*g%a==0)--great;
     73     return great-less<0?0:great-less;
     74 }
     75 void solve1() {
     76     cin >> a >> b;
     77     ll res = 0;
     78     //if(a % b == 0) res++;
     79     for (int i = b; i <= a; i += b) {
     80         int now = a;
     81         if(now % i == 0) res++;
     82         res += work(i, i + 1, now);
     83         res += work(i, i + 2, now);
     84         for (int j = 1; ; j++) {
     85             int t = now - i * j;
     86             if(t <= 0) break;
     87             res += work(i + 1, i + 2, t);
     88         }
     89         //cout << i << " " << res << endl;
     90     }
     91     cout << res << endl;
     92 }
     93 ll work2(int a, int b, int c) {
     94     int x, y;
     95     ll t = exgcd(a, b, x, y);
     96     //cout << t << " " << x << " " << y << endl;
     97     if(c % t != 0) return 0;
     98     ll f = c / t;
     99     //double z1 = 1.0 * -x * f * t / b;
    100     //double z2 = 1.0 * y * f * t / a;
    101     //int x1 = z1, x2 = z2;
    102     ll t1 = floor(1.0 * -x * f * t / b);
    103     ll t2 = floor(1.0 * y * f * t / a);
    104     //cerr << z1 << " " << x1 << " " << t1 << " " << z2 << " " << x2 << " " << t2 << endl;
    105     if(1ll * -x * f * t % b == 0) t1--;
    106     return t2 - t1 < 0 ? 0 : t2 - t1;
    107 }
    108 void solve() {
    109     cin >> a >> b;
    110     ll res = 0;
    111     //if(a % b == 0) res++;
    112     for (int i = b; i <= a; i += b) {
    113         //int now = a - b;
    114         for (int j = 1; ; j++) {
    115             int now = a - i * j;
    116             if(now < 0) break;
    117             res += work2(i + 1, i + 2, now);
    118         }
    119 
    120         //cout << i << " " << res << endl;
    121     }
    122     cout << res << endl;
    123 }
    124 int main() {
    125     freopen("test.in", "r", stdin);
    126     freopen("test.out", "w", stdout);
    127     //freopen("test.err", "w", stderr);
    128     //cout << __builtin_popcount(11) << endl;
    129     //return 1;
    130     //cout << work(2, 3, 5) << endl;
    131     //return 0;
    132     int _;
    133     cin >> _;
    134     for (int i = 1; i <= _; i++) {
    135         cout << "Case #" << i << ": ";
    136         solve();
    137     }
    138     return 0;
    139 }
  • 相关阅读:
    Python3学习之路~8.5 SocketServer实现多并发
    Python3学习之路~8.4 利用socket实现文件传送+MD5校验
    [jzyzoj2021]lca模板题
    [BZOJ4542] [JZYZOJ2014][Hnoi2016] 大数(莫队+离散化)
    BZOJ3289[JZYZOJP2018]: Mato的文件管理 莫队+树状数组+离散化
    离散化的后续
    数据离散化 ( 以及 stl 中的 unique( ) 的用法 )+ bzoj3289:Mato的文件管理
    stl upper_bound()
    [BZOJ 3720][JZYZOJ 2016]gty的妹子树 强制在线 树分块/树套树
    所以学树分块的时候为什么要看vector啊sjb
  • 原文地址:https://www.cnblogs.com/y119777/p/6126389.html
Copyright © 2011-2022 走看看