要是我們能預處理出i-四面體的方案數,那麼我們查詢時分治fft即可
注意fft時要預處理單位複數根來保證精度
考慮如何預處理出i-四面體的方案數
我們可以打表得到乙個num陣列
num[0]=1
num[1]=12
num[2]=54
num[3]=108
num[4]=81
numi代表2-四面體去掉i條邊的方案數
那麼我們可以得到k-四面體的方案數(k>=3):
∑ i=
04nu
mi∗∑
j=ma
x(0,
k−i)
6∗k−
12(6∗
k−12j
)\sum_^num_*\sum_^\binom
∑i=04
numi
∗∑j
=max
(0,k
−i)6
∗k−1
2(j
6∗k−
12)
k=1,2時,方案數分別為9,243
我們的問題轉化成了如何對每個k求
∑ i=
0k(6
∗k−12
i)
\sum_^\binom
∑i=0k
(i6∗
k−12
)可以輕鬆地o(n
)o(n)
o(n)
求出時間複雜度:o(n
+nlo
g2nl
og2n
)o(n+nlog_nlog_n)
o(n+nl
og2
nlog
2n)
#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
const int mod=100003;
int n,k;
#define maxn 60010
#define pi acos(-1)
int f[maxn];
int val[maxn];
int fact[maxn*2],inv[maxn*2];
int num[5]=;
inline int c(int i,int j)
return ans;
}struct cp;}
friend cp operator -(cp &num1,cp &num2);}
friend cp operator *(cp &num1,cp &num2);}
friend cp operator /(cp &num,int t);}
}t1[maxn*2],t2[maxn*2],*wr[16];
int rev[maxn*2],len,bit;
inline void wpre()
int mid=(l+r)>>1;
solve(k<<1,l,mid);
solve(k<<1|1,mid+1,r);
int l1=g[k<<1].size()-1,l2=g[k<<1|1].size()-1;
len=1;bit=0;
while(len<=l1+l2)len<<=1,bit++;
for(int i=0;i>1]>>1)|((i&1)<<(bit-1));
for(int i=0;i=max(i-5,0);--j)
val[i]=(64ll*tmp+val[i])%mod;
val[i]=(val[i]+c(6*(i-1)-12,i))%mod;
}for(register int i=3;i<=60000;++i)
}int t;
scanf("%d",&t);
while(t--)
return 0;
}
NYOJ 題目32組合數
時間限制 3000 ms 記憶體限制 65535 kb 難度 3 描述 找出從自然數1 2 n 0 輸入 輸入n r。輸出按特定順序輸出所有組合。特定順序 每乙個組合中的值從大到小排列,組合之間按逆字典序排列。樣例輸入 5 3 樣例輸出 543 542541 532531 521432 431421...
1056 組合數的和
1.解題思路 用sum統計所有可能組合出來的兩位數字之和,在sum累加的過程中 對於每乙個輸入的數字temp,都能和其他n 1個數字組合出新的數字 temp能夠放在個位也能夠放在十位,所以每個數字temp都能在個位出現 n 1 次 十位出現 n 1 次,在個位產生的累加效果為temp n 1 而在十...
7 7 組合數的和
給定 n 個非 0 的個位數字,用其中任意 2 個數字都可以組合成 1 個 2 位的數字。要求所有可能組合出來的 2 位數字的和。例如給定 2 5 8,則可以組合出 25 28 52 58 82 85,它們的和為330。輸入格式 輸入在一行中先給出 n 1 n 10 隨後給出 n 個不同的非 0 個...