代码源#960. 一个大整数(用DP实现组合计数)
作者:互联网
题目:
给出一个很大的整数x,以质因数分解的方式给出,请问有多少对x的因子是互质的。
分析:
来枚举一下样例,可以发现12的因子有1,2,3,4,6,12。互质的因子对为(1, 1), (1, 2), (1, 3), (1, 4), (1, 6),(1, 12), (2, 1), (2, 3), (3, 1), (3, 2),(3, 4), (4, 1), (4, 3), (6, 1), (12, 1),共15对。
通过简单的猜想,我们可以得出结论,同一个质因子的不同次幂数不能组成互质的因子对,而质因数(也就是底数)不同的一定可以构成互质的因子对。因此,我们可以将问题抽象成一个取球问题,每个质因数代表一个种类的球,这种球的个数就是该质因数的次幂,那么我们要做的就是任取两种球组成一对。
实现:
虽然思路是组合计数,但是略做思考发现通过排列组合很难去处理这类问题,会造成重复的计数。我们突然发现每一类球的选取策略很简单,对于一种球,我们有三种处理方式,第一是把他放在左边,第二把他放在右边,第三就是不放他。那么答案就是\(\prod_{i=1}^n(2 * c_i + 1)\)
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, n) for(int i = a; i < n; i++)
#define all(x) x.begin(), x.end()
#define pb push_back
#define ios ios::sync_with_stdio(false);cin.tie(0);
#define debug(x) cout << x << endl;
#define SZ(x) (int)x.size()
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f;
void read(int &x) {int s = 0, f = 1; char ch = getchar(); while(!isdigit(ch)) {f = (ch == '-' ? -1 : f); ch = getchar();} while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();} x = s * f;}
const int mod = 1e9 + 7;
const int N = 10005;
int n;
void solve()
{
scanf("%d", &n);
int p, c;
rep(i, 1, n + 1)
scanf("%d%d", &p, &c), res = res * (2ll * c + 1) % mod;
printf("%lld"\n, res);
}
signed main()
{
int _ = 1;
scanf("%d", &_);
while(_--)
solve();
}
标签:ch,960,int,计数,因子,12,互质,DP,define 来源: https://www.cnblogs.com/DM11/p/16648172.html