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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ1406: [AHOI2007]密码箱 数论

發布時間:2025/4/16 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ1406: [AHOI2007]密码箱 数论 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

在一次偶然的情況下,小可可得到了一個密碼箱,聽說里面藏著一份古代流傳下來的藏寶圖,只要能破解密碼就能打開箱子,而箱子背面刻著的古代圖標,就是對密碼的提示。經過艱苦的破譯,小可可發現,這些圖標表示一個數以及這個數與密碼的關系。假設這個數是n,密碼為x,那么可以得到如下表述: 密碼x大于等于0,且小于n,而x的平方除以n,得到的余數為1。 小可可知道滿足上述條件的x可能不止一個,所以一定要把所有滿足條件的x計算出來,密碼肯定就在其中。計算的過程是很艱苦的,你能否編寫一個程序來幫助小可可呢?(題中x,n均為正整數)

Input

輸入文件只有一行,且只有一個數字n(1<=n<=2,000,000,000)。

Output

你的程序需要找到所有滿足前面所描述條件的x,如果不存在這樣的x,你的程序只需輸出一行“None”(引號不輸出),否則請按照從小到大的順序輸出這些x,每行一個數。

Sample Input

12

Sample Output

1
5
7
11

Solution

首先考慮怎么去掉這個mod

$$x^2\ mod\ n\ =\ 1 $$

可以化為

$$kn=x^2-1$$

$$kn=(x+1)(x-1)$$

即$$n|(x+1)(x-1)$$

所以枚舉$n$的因數來算就好,注意要枚舉大因數,小因數TLE的很慘...

可以拿set來存答案也可以最后把答案排序一遍

#include <bits/stdc++.h>#define ll long long #define inf 0x3f3f3f3f #define il inlinenamespace io {#define in(a) a=read()#define out(a) write(a)#define outn(a) out(a),putchar('\n')#define I_int llinline I_int read() {I_int x = 0 , f = 1 ; char c = getchar() ;while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; }while( c >= '0' && c <= '9' ) { x = x * 10 + c - '0' ; c = getchar() ; }return x * f ;}char F[ 200 ] ;inline void write( I_int x ) {I_int tmp = x > 0 ? x : -x ;if( x < 0 ) putchar( '-' ) ;int cnt = 0 ;while( tmp > 0 ) {F[ cnt ++ ] = tmp % 10 + '0' ;tmp /= 10 ;}while( cnt > 0 ) putchar( F[ -- cnt ] ) ;}#undef I_int} using namespace io ;using namespace std ;#define N 100010//x^2 mod n = 1 //kn = x^2 - 1 //n | x^2 - 1 //n | (x+1)(x-1) ll n = read() ; ll st[ N ] ; int top = 0 ; int cnt[ N ] ;int main() {for( ll i = 1 ; i * i <= n ; i ++ ) {if( n % i == 0 ) {st[ ++ top ] = n / i ;}}int tot = 0 ;while( top ) {ll tmp = st[ top ] ;for( ; tmp <= n ; tmp += st[ top ] ) {if( ( tmp - 2 ) % ( n / st[ top ] ) == 0 ) cnt[ ++ tot ] = ( tmp - 1 ) % n ;if( ( tmp + 2 ) % ( n / st[ top ] ) == 0 ) cnt[ ++ tot ] = ( tmp + 1 ) % n ;}top -- ;}if( !tot ) puts("None") ;else {sort( cnt + 1 , cnt + tot + 1 ) ;for( int i = 1 ; i <= tot ; i ++ ) {if( cnt[ i ] != cnt[ i - 1 ] ) outn( cnt[ i ] ) ;}}return 0 ; }

?

轉載于:https://www.cnblogs.com/henry-1202/p/BZOJ1406.html

總結

以上是生活随笔為你收集整理的BZOJ1406: [AHOI2007]密码箱 数论的全部內容,希望文章能夠幫你解決所遇到的問題。

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