[codeforces 893E] Counting Arrays
给定x,y。
求长度为y的整数数组,它的所有数的成绩为x的数组的个数。
题解:
有数组里有负数的话就在正数的基础上直接乘2^(y-1)
考虑全部都是正数,你只要质因数分解,枚举每个位置上放多少个质因子p,直接用组合数算我没推出来,后面发现,质因子个数是log的,就直接dp出了计数数组后面知道然而就是C(x+i,i)。
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <ctime> #include <iostream> const int mod = 1e9+7; int q, prime[1000010], flag[1000010], pt, f[1000010][25]; int fpow(int a, int x) { int res = 1; for(; x; x >>= 1) { if(x&1) res = 1ll*res*a%mod; a = 1ll*a*a%mod; } return res; } int main() { scanf("%d", &q); for(int i = 2; i <= 1000; i++) if(!flag[i]) { prime[++pt] = i; for(int j = i*i; j <= 1000000; j += i) flag[j] = 1; } for(int i = 1; i <= 1000000; i++) f[i][0] = 1; for(int i = 1; i <= 20; i++) f[0][i] = 1; for(int i = 1; i <= 1000000; i++) for(int j = 1; j <= 20; j++) f[i][j] = (f[i-1][j]+f[i][j-1])%mod; while(q--) { int x, y; scanf("%d%d", &x, &y); int ans = 1; for(int i = 1; i <= pt && prime[i]*prime[i] <= x; ++i) { int cnt = 0, v = 1; while(x%prime[i] == 0) { x /= prime[i]; cnt++; v = 1ll*v*cnt%mod; } if(!cnt) continue; //printf("%d %d %d\n", prime[i], cnt, v); int now = 1ll*f[y-1][cnt]%mod; ans = 1ll*ans*now%mod; } if(x != 1) ans = 1ll*ans*f[y-1][1]%mod; ans = 1ll*ans*fpow(2, y-1)%mod; printf("%d\n", ans); } return 0; }