Ural 1091 Tmutarakan Exams【容斥原理】

题目链接:

http://acm.timus.ru/problem.aspx?space=1&num=1091

题目大意:

给你两个整数K和S,从小于等于S的非负整数中选择K个数,并且K个数的最大公约数大于1,

问总共有多少组。(2 <= K <= S <= 50)。

解题思路:

因为 2 <= K <= S <= 50,我们可以直接枚举质因数,求出从每个质因数的倍数中选择k个数

的组合数,累加起来即为方案个数,但是这样重复计算了很多情况。

例如:S = 20,K = 2。

2的倍数:2、4、6、8、10、12、14、16、18、20

3的倍数:3、6、9、12、15、18

5的倍数:5、10、15、20

7的倍数:7、14

11的倍数:11

……

如果单纯累加的话,很多数都重复计算了多次。应该去掉重复多加的部分。相当于把2的倍数、

3的倍数、…全部看作一个个的集合,求每部分的组合情况,然后求集合的并集。

如果2的倍数集合中选取K的数的方案数为P(2),所求结果为:

P(2)+P(3)+…+P(23)-P(2*3)-P(2*5)....(2*11) + P(2*3*5) + ……

因为S最大数不超过50,K最小数为2,则2*29 = 54 > 50了,所以质因数枚举到23即可。

求集合的并集利用容斥原理来做。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int Prime[22] = {2,3,5,7,11,13,17,19,23,29};

int C(int n,int m)
{
    if(n < m)   //不加就错
        return 0;
    m = min(m, n-m);
    int ans = 1;
    for(int i = 1; i <= m; ++i)
    {
        ans *= (n-i+1);
        ans /= i;
    }
    return ans;
}

int K,S;

int Solve()
{
    int ans = 0,top = 0;
    for(int i = 0; i < 10; ++i)
    {
        if(S / Prime[i] < K)
        {
            top = i;
            break;
        }
    }

    for(int i = 1; i < (1 << top); ++i)
    {
        int odd = 0,Mult = 1;
        for(int j = 0;  j < top; ++j)
        {
            if((1 << j) & i)
            {
                odd++;
                Mult *= Prime[j];
            }
        }
        if(odd & 1)
            ans += C(S / Mult, K);
        else
            ans -= C(S / Mult, K);
    }

    if(ans <= 10000)
        return ans;
    else
        return 10000;
}

int main()
{
    while(~scanf("%d%d",&K,&S))
    {
        printf("%d\n",Solve());
    }

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 13:53:09

Ural 1091 Tmutarakan Exams【容斥原理】的相关文章

Ural 1091 Tmutarakan Exams

Tmutarakan Exams Time Limit: 1000ms Memory Limit: 16384KB This problem will be judged on Ural. Original ID: 109164-bit integer IO format: %lld      Java class name: (Any) University of New Tmutarakan trains the first-class specialists in mental arith

URAL 1091. Tmutarakan Exams(容斥原理)

题目链接 题意 : 给你两个数k,s,让你找k个数,这k个数都不大于s,并且这k个数的公约数大于1. 思路 : 枚举一下素数倍数,求组合数,最后容斥原理求最终结果. 当k=3,s=20的时候 : 2 : 2 4 6 8 10 12 14 16 18 20 3 :3 6 9 12 15 18 5 :5 10 15 20 只要从每个集合里边找出k个即可,这就是用组合数了.但是会有重复的,例如 2 : 6 12 18 3 : 6 12 18 这样就多加了一个,要再减去,所以就是容斥原理.加一个的减两个

URAL 1091. Tmutarakan Exams 容斥

从1到s选出k个数 他们的最大公约数大于1 求方案数 容斥 S(1)-S(2)+S(3) S(x)为选出k个数的公因子个数为x的数量 #include <cstdio> #include <cmath> #include <cstring> using namespace std; typedef long long LL; const int maxn = 55; int prime[maxn], vis[maxn]; int n, m; int get_primes

2014 Super Training #3 H Tmutarakan Exams --容斥原理

原题: URAL 1091  http://acm.timus.ru/problem.aspx?space=1&num=1091 题意:要求找出K个不同的数字使他们有一个大于1的公约数,且所有的数字都不能大于一个指定的数字S. 解法:可以考虑每个S内的素数,此素数和它的所有倍数构成一个集合,则可以在这些集合中任意去k个元素,C(n,k)即为这种情况下的方法种数,比如K = 3,S = 10, 则可以形成3个集合: {2,4,6,8,10} , {3,6,9}, {5,10} ,第一个集合C(5,

1091. Tmutarakan Exams

1091. Tmutarakan Exams Time limit: 1.0 secondMemory limit: 64 MB University of New Tmutarakan trains the first-class specialists in mental arithmetic. To enter the University you should master arithmetic perfectly. One of the entrance exams at the Di

F - Tmutarakan Exams URAL - 1091 -莫比乌斯函数-容斥 or DP计数

F - Tmutarakan Exams 题意 : 从 < = S 的 数 中 选 出 K 个 不 同 的 数 并 且 gcd > 1 .求方案数. 思路 :记 录 一 下 每 个 数 的 倍 数 vector 存 储 ,最后从 2 开始 遍历 一遍每个数 ,从 他的倍数中 挑选 k个 组合数求解. 但是会有重复,因为 比如 K=2,S=15时 , 2倍数 : 2  ,4 , 6,  8, 10,  12, 14 ,   挑出了 这种情况 6 ,12,然后 从3的倍数 : 3, 6 ,9,12

ural 1932 The Secret of Identifier (容斥原理)

题目大意: 求出给的n个串中. 精确到只有一个字符不同,两个字符不同,三个字符不同,四个字符不同的对数. 思路分析: 枚举状态. dp[i] [j] ...表示当前串取出 i 状态下的所有字符转化成十进制数为 j 的出现的次数. 这样的话,就记录了所有串的子串的状态. 然后计数就得到了所有的状态. 然后我们要得到精确不同的,可以用补集的思想,如果要精确到三个不相同,意味着要精确到1 个是相同的. 注意的问题是 在最后要运用容斥去重. #include <cstdio> #include <

URAL 1907. Coffee and Buns(数论推导+容斥原理)

1907. Coffee and Buns Time limit: 1.0 second Memory limit: 64 MB Planet Ataraxia is known for its education centers. The people who are expected to take high social positions in future are brought up in conditions of continuous training and supervisi

POJ 1091 容斥原理

链接: http://poj.org/problem?id=1091 题意: 给你两个正整数n,m,让你求长度为n+1的满足条件的一个等式:a[1]*x1+a[2]*x2+a[3]*x3+...+a[n]*xn+a[n+1]*x(n+1)=1 (0<=a[i]<=m&&a[n+1]=m) 让你求一共有多少种情况满足这个条件. 要使得 a[1]*x1+a[2]*x2+a[3]*x3+...+a[n]*xn+a[n+1]*m=1 (0<=a[i]<=m),那么a[1],