UVA 11076 Add Again 计算对答案的贡献+组合数学

A pair of numbers has a unique LCM but a single number can be the LCM of more than one possible
pairs. For example 12 is the LCM of (1, 12), (2, 12), (3,4) etc. For a given positive integer N, the
number of different integer pairs with LCM is equal to N can be called the LCM cardinality of that
number N. In this problem your job is to find out the LCM cardinality of a number.
Input
The input file contains at most 101 lines of inputs. Each line contains an integer N (0 < N ≤ 2 ∗ 109
).
Input is terminated by a line containing a single zero. This line should not be processed.
Output
For each line of input except the last one produce one line of output. This line contains two integers
N and C. Here N is the input number and C is its cardinality. These two numbers are separated by a
single space.
Sample Input
2
12
24
101101291
0
Sample Output
2 2
12 8
24 11
101101291 5

题意:给出一个序列,要求将所有可能的序列每个序列形成的数值相加的和。

题解:计算每个位置上可能放的数是哪些,计算对答案的贡献的一种,利用到了组合数学,可以类似求杨辉三角去求组合数

//meek///#include<bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<bitset>
#include<map>
using namespace std ;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
#define fi first
#define se second
#define MP make_pair
typedef long long ll;

const int N = 20;
const int M = 1000001;
const int inf = 0x3f3f3f3f;
const int MOD = 1000000007;
const double eps = 0.000001;

ll ans,c[N][N];
int a[N],v[N],n;
ll add(){
   int k = n-1;
   ll t = 1;
   for(int i=0;i<10;i++) {
    t *= c[k][v[i]];
    k -= v[i];
   }
    return t;
}
int main() {
    for(int i=0;i<=12;i++) {
        c[i][0] = 1;
        for(int j=1;j<=i;j++)
            c[i][j] = c[i-1][j-1] + c[i-1][j];
    }
    while(~scanf("%d",&n)) {
        if(n==0)break;
        mem(v);ans = 0;
        ll sum = 0;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),v[a[i]]++;
        for(ll i=0;i<=9;i++) {
            if(v[i]) {
                v[i]--;
                ll tmp = add();
                v[i]++;
                sum += i*tmp;
            }
        }
        ans = 0;
        for(int i=1;i<=n;i++) ans = ans*10 + sum;
        printf("%lld
",ans);
    }
    return 0;
}
代码
原文地址:https://www.cnblogs.com/zxhl/p/5078507.html