ほぼ雑記的メモ
フェルマーによると、3で割ると1余る素数は x^2 + 3y^2 (ただしx, yは整数)と表すことができるそうな。 というわけで、先日見つけた素数 5316666001 は 3n+1型なので、そのように表せるわけですが トリビアルなやりかた(1から順番に探していく)方法だと、結構大変。特に素数がでかくなると、計算量が半端ないようで。 答え分かりますか? 72151^2 + 3*6080^2 = 5316666001 まずは x^2 + 3 = 0 (mod p)なる xを探すところから始まるわけですが、 特定の型ではうまく言っても、一般的にとなるとこれが結構しんどかった。 原始根の指数との対応が求まれば簡単に計算できるのだけど、指数を求めるのは 計算として難しいと言われていること(DH鍵交換はこれが計算するのが難しいという 大前提で成立している) 散々悩んだ末、p-1の素因数の和くらいのオーダで計算ができるようになりました。 p-1が大きな素因数を持っていないなら、これなら100桁くらいでも大丈夫でしょう。 こういうのを考え始めるとキリがないなぁ。楕円関数使うともっと効率よさそうなのがありそうだけど、考えるのが面倒なのでペンディング。 なお4n+1型の2つの平方の和で表すほうはとても簡単に求まります。ハイ
追記) 確率的アルゴリズムを用いればp-1の素因数が大きくても問題ないです。詳しくは関連を
もし話し合いというのを許すなら、4人の場合は次のようにすればよいでしょう。 1)A、BとC、Dのグループにわける。 2)A、B連合は相談して山を二つに分ける。 3)C、D連合は相談してどちらかの山を先に選ぶ。 4)あとは、それぞれの山を二人で先ほどのように分ければよい。 しかし話し合いをしているヒマすらないという場合も考えられますし、 そもそも決裂してしまったら意味がない。しかも3人の場合はどうするんだ? とか考えると、もっとよいやり方があるのかなぁ・・と 1)Aが3つに分ける。 2)Bが1つの山を選ぶ 3)Cがさらに1つの山を選ぶ。もし、B、Cが別の山を選べば、それで確定。 4)B、Cが同じ山を選んだとすれば、Aは残りの山のどちらかから1つ選ぶ。 5)残った2つの山を1つにまとめ、Bが再配分。先にCが選び、残りをBとする。 これでいいような気がするけど、ちょっと問題があるんですよねぇ。 100の宝石を分けるとき、Aが1,49,50と分けたとします。 B、Cが二人とも50を選ぶことはありません。Bが選んだあとCも50を選ぶとすると、Aは49を選ぶことになり、その結果B、Cは51を二人で分け合うことになるからです。これは損です。 よって、Cは49を選ぶしかない。つまり、このケースではBの選択権が強すぎて、 Cはどう転んでも最大利益の50を選ぶ権利がありません。 じゃぁ、B、Cが同じのを選択したときはCに権利があるとすると、 今度はCの選択権が強すぎてBはどう転んでも50を選べない。 よってこの方法では手詰まりです。 なんかもっとうまい方法はないですかねぇ?じゃんけんすれば一発という解答はなしの方向でw
2^11-1 23 * 89 2^23-1 47 * 178481 2^29-1 233 * 1103 * 2089 2^41-1 13367 * 164511353 2^43-1 431 * 9719 * 2099863 2^47-1 2351 * 4513 * 13264529 2^53-1 6361 * 69431 * 20394401 2^59-1 179951 * 3203431780337 2^67-1 193707721 * 761838257287 2^71-1 228479 * 48544121 * 212885833 2^73-1 439 * 2298041 * 21514198099633918969? 2^79-1 2687 * 202029703 * 224958284260258499201? 2^83-1 167 * 57912614113275649087721? 2^97-1 11447 * 13842607235828485645766393? 2^101-1 7432339208719 * 341117531003194129? 2^103-1 2550183799 * 3976656429941438590393? 2^109-1 745988807 * 870035986098720987332873? 2^113-1 3391 * 65993 * 23279 * 1868569 * 1066818132868207? 2^131-1 263 * 10350794431055162386718619237468234569?
def gcd(a, b) while true if a > b a %= b return b if a == 0 else b %= a return a if b == 0 end end end
def gcd(a, b) while true if a > b return b if (a %= b) == 0 else return a if (b %= a) == 0 end end end
def gcd(a, b) while true return b if (a %= b) == 0 return a if (b %= a) == 0 end end
int gcd(int a, int b) { while(1){ if(!(a %= b)) return b; if(!(b %= a)) return a; } }