题目:
题目分析:
假设共有n位,先考虑可重复,对于每一个数字x,它对总和做出的贡献为11…111(n个1)* (n - 1) ! * x
因此设sum = sigma ai * i
那么可重复的总和即为11…111(n个1)* (n - 1) ! * sum
那么对不可重复而言,我们只需除以每一个ai的排列之积即可
代码如下:
#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 << Sum << ' ' << part_I << ' ' << part_mul << ' ' << part_div << endl;
cout << (LL)Sum * part_I %mod * part_mul %mod * part_div % mod << endl;
}
代码分析:
1.pow用平方的方式,快速求取余的次方
2.part_I记录n个1
3.part_mul记录count-1的阶乘
4.part_div记录每一个ai的排列之积的相反数(why?我们这里直接除可以吗?)
总结:
1.typedef long long LL写法
2.1e9+7写法