51nod 1040 1060 (數論)
51nod 1040 傳送門:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1040
求1-n與n的gcd之和,n<=1e9
一個一個求肯定是不行的,所以需要一些方法咯
首先,如果x與n的gcd為gcd(x,n),所以gcd(x/gcd(x,n),n/gcd(x,n))=1,所以我們可以搜尋n的因子nn,然後求nn的尤拉函式(與nngcd為1的數字個數為tmp),然後tmp*n/nn就是gcd為n/nn的數字的gcd之和。
先求出n的尤拉函式phi,然後對於一個素因子k,如果k只有一個,n/k的尤拉函式為phi/(k-1),否則n/k的尤拉函式為phi/k
通過搜尋n的每一個因子,答案為sigma(phi[d]*n/d)(d|n)
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define MAX 1000005 #define MAXN 1000005 #define maxnode 15 #define sigma_size 30 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lrt rt<<1 #define rrt rt<<1|1 #define middle int m=(r+l)>>1 #define LL long long #define ull unsigned long long #define mem(x,v) memset(x,v,sizeof(x)) #define lowbit(x) (x&-x) #define pii pair<int,int> #define bits(a) __builtin_popcount(a) #define mk make_pair #define limit 10000 //const int prime = 999983; const int INF = 0x3f3f3f3f; const LL INFF = 0x3f3f; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-8; const LL mod = 1e9+7; const ull mx = 133333331; /*****************************************************/ inline void RI(int &x) { char c; while((c=getchar())<'0' || c>'9'); x=c-'0'; while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; } /*****************************************************/ bool prime[100005]; int pr[100005]; int tot; vector<int> v; set<int> s; LL ans; int n; void init(){ mem(prime,0);tot=0; for(int i=2;i<100000;i++){ if(!prime[i]){ for(int j=2*i;j<100000;j+=i) prime[j]=1; pr[tot++]=i; } } } void dfs(int x,int ph,int j){ if(s.count(x)) return ; else{ s.insert(x); ans+=(LL)ph*(n/x); } for(int i=j;i<v.size();i++){ int tmp=ph; int k=x; while(k%v[i]==0){ k/=v[i]; if(k%v[i]==0) tmp/=v[i]; else tmp/=(v[i]-1); dfs(k,tmp,j+1); } } } int main(){ //freopen("in.txt","r",stdin); cin>>n; init(); v.clear(); int k=n; for(int i=0;i<tot&&pr[i]*pr[i]<=k;i++){ if(k%pr[i]==0){ while(k%pr[i]==0) k/=pr[i]; v.push_back(pr[i]); } } if(k!=1) v.push_back(k); int phi=n; for(int i=0;i<v.size();i++){ phi=phi/v[i]*(v[i]-1); } ans=0; dfs(n,phi,0); cout<<ans<<endl; return 0; }
51nod 1060 傳送門:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1060
求1-n裡面因子數量最多的,並且最小的數n<=1e18
由於1e18分解質因數,也就最多60多個數相乘,所以可以直接爆搜解決問題
因為a=p1^k1 * p2^k2 * p3^k3 *...* pn^kn
它的因子數量為(k1+1)*(k2+1)*(k3+1)*...*(kn+1)
所以搜尋時記錄當前值的大小,和這會應該搜尋的素因子pi,以及當前因子個數,每次搜尋往下都是搜尋後一種素因子,不在同一個素因子上遞迴
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <sstream> #include <cstdlib> #include <iostream> #include <algorithm> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define MAX 1000005 #define MAXN 1000005 #define maxnode 15 #define sigma_size 30 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lrt rt<<1 #define rrt rt<<1|1 #define middle int m=(r+l)>>1 #define LL long long #define ull unsigned long long #define mem(x,v) memset(x,v,sizeof(x)) #define lowbit(x) (x&-x) #define pii pair<int,int> #define bits(a) __builtin_popcount(a) #define mk make_pair #define limit 10000 //const int prime = 999983; const int INF = 0x3f3f3f3f; const LL INFF = 0x3f3f; const double pi = acos(-1.0); const double inf = 1e18; const double eps = 1e-8; const LL mod = 1e9+7; const ull mx = 133333331; /*****************************************************/ inline void RI(int &x) { char c; while((c=getchar())<'0' || c>'9'); x=c-'0'; while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; } /*****************************************************/ LL n; LL ans; int maxn; bool prime[10005]; int pr[10005]; int tot; void init(){ mem(prime,0);tot=0; for(int i=2;i<10000;i++){ if(!prime[i]){ for(int j=i*i;j<10000;j+=i) prime[j]=1; pr[tot++]=i; } } } void dfs(int f,int num,int nu,LL tmp){ LL ret=tmp; if(tmp<=n){ if(nu>maxn){ maxn=nu; ans=tmp; } else if(nu==maxn) ans=min(ans,tmp); } for(int i=1;i<=num;i++){ if(ret>n/pr[f]) break;//防止爆LL ret*=pr[f]; dfs(f+1,i,nu*(i+1),ret); } } int main(){ //freopen("in.txt","r",stdin); int t; cin>>t; init(); while(t--){ cin>>n; maxn=0; ans=0; dfs(0,100,1,1); cout<<ans<<" "<<maxn<<endl; } return 0; }
相關推薦
51nod 1040 1060 (數論)
51nod 1040 傳送門:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1040 求1-n與n的gcd之和,n<=1e9 一個一個求肯定是不行的,所以需要一些方法咯 首先,如果x與n的
(數論)51NOD 1106 質數檢測
ret == max else 篩法 %s out spa clas 給出N個正整數,檢測每個數是否為質數。如果是,輸出"Yes",否則輸出"No"。 Input 第1行:一個數N,表示正整數的數量。(1 <= N <= 1000) 第2 - N +
(數論)51NOD 1135 原根
for text 分解 fin 輸出 def gray div F12 設m是正整數,a是整數,若a模m的階等於φ(m),則稱a為模m的一個原根。(其中φ(m)表示m的歐拉函數) 給出1個質數P,找出P最小的原根。 Input 輸入1個質數P(3 <= P
51Nod 1217 - Minimum Modular(數論)
【題目描述】 【思路】 這個題我們可以考慮從小到大列舉m(從max(1,n-k)到max(a[i])+1),然後判斷能否在刪不超過k個數的情況下滿足每個數模m都互不相同。 對於模m的情況,a[i]≡a[j](mod m)當且僅當a[i]-a[j]是m的倍數,我們可以先預處理出a[i
51nod-1616 最小集合(數論)
基準時間限制:1 秒 空間限制:131072 KB 分值: 80 難度:5級演算法題 收藏 關注 A君有一個集合。 這個集合有個神奇的性質。 若X,Y屬於該集合,那麼X與Y的最大公因數也屬於該集合。 但是他忘了這個集合中原先有哪些數字。 不過幸運的是,他
UVA 10042 Smith Numbers(數論)
sizeof ret col 保存 進行 uva nal isp published Smith Numbers Background While skimming his phone directory in 1982, Albert Wilansky, a ma
[luoguP1069] 細胞分裂(數論)
def getc urn ostream lin 優先級 org return 優先 傳送門 分解質因數,不說了 這題坑了我2個多小時 教訓 不熟悉位運算的優先級一定要加括號!!!! #include <cstdio> #include &
UVA571 - Jugs(數論)
osi com con post roc defined ucc sof mic UVA571 - Jugs(數論) 題目鏈接 題目大意:給你A和B的水杯。給你三種操作:fill X:把X杯裏面加滿水。empty X:把X杯中的水清空。pou
LibreOJ #6220. sum(數論)
define onclick const 全部 註意 img long long %d mes 題目大意:在數組中找出一些數,使它們的和能被n整除 這題標簽是數學,那我就標題就寫數論好了... 顯然如果數組中有n的倍數直接取就行。 那假設數組中沒有n的
bzoj1257: [CQOI2007]余數之和sum(數論)
img const ima left class -1 找到 一段 max 非常經典的題目... 要求 則有 實際上 最多只有2*sqrt(k)種取值,非常好證明 因為>=sqrt(k)的數除k下取整得到的數一定<=sq
【LightOJ1336】Sigma Function(數論)
【LightOJ1336】Sigma Function(數論) 題面 Vjudge 求和運算是一種有趣的操作,它來源於古希臘字母σ,現在我們來求一個數字的所有因子之和。例如σ(24)=1+2+3+4+6+8+12+24=60.對於小的數字求和是非常的簡單,但是對於大數字求和就比較困難了。現在給你一個n,你需要
UVa 11582 - Colossal Fibonacci Numbers!(數論)
targe ros family tdi 計算 com fibonacci numbers def 鏈接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=
CF 980D Perfect Groups(數論)
數論 for AS AI 子串 次數 我們 main 發現 CF 980D Perfect Groups(數論) 一個數組a的子序列劃分僅當這樣是合法的:每個劃分中的任意兩個數乘積是完全平方數。定義a的權值為a的最小子序列劃分個數。現在給出一個數組b,問權值為i的b的子串
【BZOJ3240】【NOI2013】矩陣遊戲(數論)
char ++i getc getchar() 系列 HP 推導 max long long 【BZOJ3240】【NOI2013】矩陣遊戲(數論) 題面 BZOJ 題解 搞什麽矩陣十進制快速冪加卡常? 直接數學推導不好嗎? 首先觀察如何從每一行的第一個推到最後一個 \(f
【HDOJ5640】King's Cake(數論)
nbsp std namespace cas algo ima iostream turn tdi 題意: 思路: 1 #include<cstdio> 2 #include<cstdlib> 3 #include<iostream
(數論)逆元的線性算法
div 逆元 線性 ++ === class 就是 color pre 證明:/ P=K*I+R (R<I, 1<I<P); K*I+R=0(MOD P)===(兩邊同時,乘以i-1,r-1)===>i-1=-k*r-1 r-1=(p m
[Project Euler 429] Sum of squares of unitary divisors(數論)
blog ont namespace href 題解 str return void rap 題目鏈接:https://projecteuler.net/problem=429 題目: A unitary divisor dd of a number nn is a d
BZOJ2299 HAOI2011向量(數論)
條件 n) char string getchar() font while [] || 設最後的組成為x=x0a+x1b,y=y0a+y1b。那麽容易發現x0和y0奇偶性相同、x1和y1奇偶性相同。於是考慮奇偶兩種情況,問題就變為是否存在x和y使ax+by=c,那麽其
BZOJ2721 Violet5櫻花(數論)
+= || algo ont flag int math ons violet 有(x+y)n!=xy。套路地提出x和y的gcd,設為d,令ad=x,bd=y。則有(a+b)n!=abd。此時d已是和a、b無關的量。由a與b互質,得a+b與ab互質,於是將a+b除過來得
BZOJ3240 NOI2013矩陣遊戲(數論)
ring cout ios ble har using namespace tmp urn 必修五題。 // luogu-judger-enable-o2 #include<iostream> #include<cstdio> #includ