1. 程式人生 > >Tennis Game CodeForces - 496D(唯一分解定理,費馬大定理)

Tennis Game CodeForces - 496D(唯一分解定理,費馬大定理)

clu 需要 inf nbsp 出現次數 namespace net src 數加

Tennis Game

CodeForces - 496D

通過排列組合解決問題。

首先兩組不同素數的乘積,是互不相同的。這應該算是唯一分解定理的逆運用了。

然後是,輸入中的素數,任意組合,就是n的因數,而且不會重復。

然後只需要知道,每個質數在所有組合中出現了幾次就行了。

如果某一個質數再輸入中只出現了一次,那麽它在組合中出現的次數就應該是其他所有質數在輸入中出現次數加一的乘積。

如果某一個質數x在輸入中出現了多次,那麽便只需把x,x*x, x*x*x等數暫且當做一個輸入中的數來計算就是了,然後相加;容易知道這樣的話,相當於x出現次數為1,2,3,4...... 於是用等差數列求和的結果乘上上一條說的結果就行了。

之後便可以將質數的(組合中出現的次數)次方 全部乘起來就行了。

技術分享圖片
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<vector>
 4 #include<stack>
 5 #include<queue>
 6 #include<map>
 7 #include<set>
 8 #include<cstdio>
 9 #include<cstring>
10 #include<cmath>
11 #include<ctime>
12
#define fuck(x) cout<<#x<<" = "<<x<<endl; 13 #define ls (t<<1) 14 #define rs ((t<<1)+1) 15 using namespace std; 16 typedef long long ll; 17 typedef unsigned long long ull; 18 const int maxn = 1000086; 19 const int inf = 2.1e9; 20 const ll Inf = 999999999999999999; 21 const
int mod = 1000000007; 22 const double eps = 1e-6; 23 const double pi = acos(-1); 24 ll num[maxn],res[maxn]; 25 ll l[maxn],r[maxn]; 26 27 ll q_pow(ll a,ll b) 28 { 29 ll ans=1; 30 while(b){ 31 if(b&1){ans*=a;ans%=mod;} 32 a*=a;a%=mod; 33 b>>=1; 34 } 35 return ans; 36 } 37 38 int main() 39 { 40 int m; 41 scanf("%d",&m); 42 int maxx = 0; 43 for(int i=1;i<=m;i++){ 44 int x; 45 scanf("%d",&x); 46 maxx=max(maxx,x); 47 num[x]++; 48 } 49 int t=0; 50 for(int i=1;i<=maxx;i++){ 51 if(num[i]){ 52 t++; 53 res[t]=num[i]; 54 num[t]=i; 55 } 56 } 57 l[0]=1; 58 for(int i=1;i<=t;i++){ 59 l[i]=(1+res[i])*l[i-1]; 60 l[i]%=(mod-1); 61 } 62 r[t+1]=1; 63 for(int i=t;i>=1;i--){ 64 r[i]=(res[i]+1)*r[i+1]; 65 r[i]%=(mod-1); 66 } 67 68 ll ans=1; 69 for(int i=1;i<=t;i++){ 70 ll d = (l[i-1])*(r[i+1]); 71 d%=(mod-1); 72 73 ll p = res[i]*(res[i]+1)/2; 74 p%=(mod-1); 75 76 d = d*p; 77 d%=(mod-1); 78 ans*=q_pow(num[i],d); 79 ans%=mod; 80 } 81 printf("%lld",ans); 82 83 return 0; 84 }
View Code

Tennis Game CodeForces - 496D(唯一分解定理,費馬大定理)