日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

表为平方和终极版

發布時間:2024/4/11 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 表为平方和终极版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

聲明:本片文章在我的草稿箱已經塵封很久了,初稿時間是2014年9月8日,如下

?

?????

?

???? 為什么我一直沒有發出來呢? 是因為我的代碼沒有得到Yes,由于參加工作了,以后來研究的時間相對

???? 少點,現在發表出來希望有高手能指出錯誤之處,共同進步,謝謝!

?

?

?

以前寫過表為平方和初級版,鏈接為http://blog.csdn.net/acdreamers/article/details/10083393

主要的問題是求形如丟番圖方程的解。今天我將來探討另一類丟番圖方程的解,即的

解。當然,我們需要先對素因子分解,得到形如的方程,其中為奇素數。根據的不同,方程有

解的條件也不一樣。比如

?

(1)時,有解的條件是

(2)時,有解的條件是

?

接下來,我會重點以一道經典題目的解析來說明此類丟番圖方程在競賽中的應用。

?

題目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3815

?

題意:給定兩個正整數和,其中和,輸出所有滿足條件的三元組,并

???? 輸出數據滿足條件。

?

分析:本題是2014年亞洲區域賽網絡預選賽(牡丹江賽區)的G題。然而現場AC率為0,接下來進行詳細探討

?

???? 首先根據已知條件,我們可以得到如下

?

????

?

?????再令,則有

?

?????

?

???? 繼續消去,得到

?

??????

?

?????令,得到,再將素因子分解,分別求出解,

???? 然后合并即可,合并的時候跟丟番圖方程的合并類似,如下

?

???? ?

?

???? 現在的關鍵問題是如何求解丟番圖方程,其中為奇素數,此處。

?

?????那么有解的條件是,并且解唯一,求解和的方法跟上次類似,具體步驟如下

?

???? (1)先求出同余方程的最小正整數解

???? (2)對和進行輾轉相除運算,記錄每次的余數為(注意第一次的余數為),當滿足條件

???????? 時停止,此時的就是,而可以通過得到,即

?

?????????

?

代碼:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <iostream> #include <vector> #include <math.h> #include <set> #include <map>using namespace std; const int N = 255; const int M = 200005; typedef long long LL;char str[N]; LL a[N];struct Pair {LL x, y;bool operator < (const Pair &a) const{if(a.x == x) return a.y > y;return a.x > x;} }; Pair node[M];struct Res {LL x, y, z;bool operator < (const Res &a) const{if(a.x == x && a.y == y) return a.z > z;if(a.x == x) return a.y > y;return a.x > x;} };set<Pair> Set; set<Res> _Set; set<Pair> Mem; vector<LL> vec;int sign[4][2] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; int _sign[2][2] = {{-1, 1}, {1, -1}};LL multi(LL a, LL b, LL m) {LL ans = 0;a %= m;while(b){if(b & 1){ans = (ans + a) % m;b--;}b >>= 1;a = (a + a) % m;}return ans; }LL quick_mod(LL a, LL b, LL m) {LL ans = 1;a %= m;while(b){if(b & 1){ans = multi(ans, a, m);b--;}b >>= 1;a = multi(a, a, m);}return ans; }struct T {LL p, d; };LL w;T multi_er(T a, T b, LL m) {T ans;ans.p = (multi(a.p, b.p, m) + multi(multi(a.d, b.d, m), w, m)) % m;ans.d = (multi(a.p, b.d, m) + multi(a.d, b.p, m)) % m;return ans; }T power(T a, LL b, LL m) {T ans;ans.p = 1;ans.d = 0;while(b){if(b & 1){ans = multi_er(ans, a, m);b--;}b >>= 1;a = multi_er(a, a, m);}return ans; }LL Legendre(LL a, LL p) {return quick_mod(a, (p - 1) >> 1, p); }LL Work(LL n, LL p) {if(p % 3 != 1) return -1;LL a = -1, t;while(1){a = rand() % p;t = a * a - n;w = (t % p + p) % p;if(Legendre(w, p) + 1 == p) break;}T tmp;tmp.p = a;tmp.d = 1;T ans = power(tmp, (p + 1) >> 1, p);return ans.p; }LL Solve(LL n, LL p, LL &_x, LL &_y) {LL x = Work(n, p);if(x == -1)return -1;if(x >= p - x)x = p - x;LL t = p;LL r = x;LL limit = (LL)sqrt(1.0 * p);while(r > limit){x = r;r = t % x;t = x;}_x = r;_y = (LL)sqrt((p - r * r) / 3);return 0; }void Prepare(char str[], LL a[], int &cnt) {cnt = 0;LL ans = 0;bool flag = 0;int len = strlen(str);for(int i=0; i<=len; i++){if(str[i] >= '0' && str[i] <= '9')ans = ans * 10 + str[i] - '0';else if(str[i] == '-')flag = 1;else{if(flag) ans = -ans;a[cnt++] = ans;ans = 0;flag = 0;}} }bool getData(Pair node[], LL a[], int &cnt) {int k = 0;int _cnt = 0;for(int i = 0; i < cnt; i++){if(a[i] == 2) k++;if(k == 2){node[_cnt].x = 1;node[_cnt].y = 1;_cnt++;k = 0;}if(a[i] > 2){LL x, y;int ans = Solve(-3, a[i], x, y);if(ans == -1) return false;node[_cnt].x = x;node[_cnt].y = y;_cnt++;}}cnt = _cnt;if(k == 1) return false;return true; }void dfs(int dept, int cnt, Pair ans) {if(dept == cnt - 1){Set.insert(ans);return;}for(int i = 0; i < 4; i++){for(int j = 0; j < 2; j++){Pair _ans;_ans.x = ans.x * sign[i][0] * node[dept + 1].x + _sign[j][0] * 3 * ans.y * sign[i][1] * node[dept + 1].y;_ans.y = ans.x * sign[i][1] * node[dept + 1].y + _sign[j][1] * ans.y * sign[i][0] * node[dept + 1].x;if(Mem.find(_ans) != Mem.end()) return;Mem.insert(_ans);dfs(dept + 1, cnt, _ans);}} }void Merge(Pair node[], int cnt) {Pair ans;for(int i = 0; i < 4; i++){ans.x = sign[i][0] * node[0].x;ans.y = sign[i][1] * node[0].y;Mem.insert(ans);dfs(0, cnt, ans);} }void Filter(LL B) {set<Pair>::iterator it;for(it = Set.begin(); it != Set.end(); it++){LL a = it->x - it->y;if(a & 1) continue;a >>= 1;LL b = it->y;LL c = -a - b;LL _x = B + a - c;if(_x % 3) continue;_x /= 3;LL _y = _x - a;LL _z = _x + c;if(_x > _z) swap(_x, _z);if(_y > _z) swap(_y, _z);if(_x > _y) swap(_x, _y);Res res;res.x = _x;res.y = _y;res.z = _z;_Set.insert(res);}set<Res>::iterator _it;for(_it = _Set.begin(); _it != _Set.end(); _it++)printf("%lld %lld %lld\n", _it->x, _it->y, _it->z); }void Response(LL a[], int cnt) {LL A = a[0];LL B = a[1];LL n = 3 * A - B * B;if(n == 0 && B % 3 == 0){printf("%lld %lld %lld\n", B / 3, B / 3, B / 3);return;}if(n < 2) return;a += 2;cnt -= 2;sort(a, a + cnt);for(int i = 0; i < cnt; i++){while(n % a[i] == 0){vec.push_back(a[i]);n /= a[i];}}cnt = 0;vector<LL>::iterator it;for(it = vec.begin(); it != vec.end(); it++)a[cnt++] = *it;for(int i = cnt; i >= 1; i--)a[i] = a[i-1];a[0] = 2;cnt++;if(!getData(node, a, cnt)) return;Merge(node, cnt);Filter(B); }int main() {int T;scanf("%d", &T);getchar();for(int t = 1; t <= T; t++){vec.clear();Mem.clear();Set.clear();_Set.clear();int cnt;gets(str);Prepare(str, a, cnt);printf("Case #%d:\n", t);Response(a, cnt);}return 0; }


?

最后附上鳥神的思路,雖然我不懂,但我感覺好厲害!!!

?

?

?

?

?

?

總結

以上是生活随笔為你收集整理的表为平方和终极版的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。