G List it all
生活随笔
收集整理的這篇文章主要介紹了
G List it all
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送
題意:
題解:
我們來考慮以下樣例:1,1,2
我們先考慮1的貢獻:如圖(圖中只花了)
2!表示還剩兩個空位,還有兩個數未填入,所以是2!個
對于n個數重復,考慮重復的情況就是:111…11(一共n個)* (n-1)! * sum
sum為Σa[i] * i,即每個數出現的次數 *這個數的總和
然后考慮去重:
1,1,2所組成的重復情況有:
112,112
其中我用()括號來將1分號
1(1)1(2)2,1(2)1(1)2
也就是雖然這兩個的1是不同貢獻的,但是最終組成結果一樣,所以要去掉,怎么去?在這個例子中除以2,因為有兩個1重復了。那我們現在用1,1,1,2組成重復情況有:1112,1112,1112,1112,1112,1112,會發現有6個重復情況,因為三個1全排列有6種情況,所以我們除以6,也就是重復x次,就除以x!,注意除了1重復,2也有可能,所以每個數都要去除重復,我們設a[i]表示第i個數出現的次數所以就要除以(a[1]!*a[2]!..a[9]!)
總結答案就是:
ans=(11…111(一共n個1)) * (n-1) * sum/(a[1]!*a[2]!..a[9]!)
答案要取模
代碼:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; const int N = 1e6 + 5; const int mod = 1e9 + 7; int fac[N], ifac[N]; int T[20]; typedef long long LL;int pow(int a, int b) {LL res = 1;for(;b;b >>= 1, a = (LL) a * a % mod) if (b & 1) res = res * a % mod;return res; }int main() {int Max = 1000000;fac[0] = 1;for(int i = 1; i <= Max; ++ i) fac[i] = (LL)fac[i - 1] * i % mod;ifac[Max] = pow(fac[Max], mod - 2);for(int i = Max-1; i >= 0; -- i) ifac[i] = (LL)ifac[i + 1] * (i + 1) % mod;LL Sum = 0;int Count = 0;for(int i = 1; i <= 9; ++ i) {int temp;cin >> temp;T[i] = temp;Sum += i * temp;Count += T[i];} Sum %= mod;LL part_I = 0;for(int i = 1; i <= Count; ++ i) part_I = (part_I * 10 + 1) % mod;LL part_mul = fac[Count - 1];LL part_div = 1;for(int i = 1; i<= 9; ++ i) part_div = part_div * ifac[T[i]] % mod;cout << (LL)Sum * part_I %mod * part_mul %mod * part_div % mod << endl; }總結
以上是生活随笔為你收集整理的G List it all的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Super Jumping! Jumpi
- 下一篇: HDU 5510 Bazinga