容斥原理

3 篇文章 0 订阅
2 篇文章 0 订阅

容斥原理


今天学习了容斥原理
nice
上述为容斥原理的公式,推导建议百度。我们发现,当我们要求一个集合的并集的时候,可以很好的利用容斥原理来求解。那么我们可以得到一些很好的性质。

注意到
  • 偶数个集合的交集前为加号,而奇数个集合交集前面为减号。
  • 项的个数为2^k,原理为n个集合的排列组合

那么我们可以解决如下问题

HDU-4135 : https://vjudge.net/problem/HDU-4135

1 到 n 里面有多少个和 m 互质的数?

利用容斥原理的思想,可以先求 1n 中有多少数和m不互质,我们发现,一个数和m不互质,那么它一定不是m的质因子的倍数,那么设m有质因子 p1 p2pn 那么对于质因子 pi 集合中就有 n/pi 个和 m 不互质的数,那么对应了n 个集合那么 pi pj 的交集里就有 n/(pi*pj) 个数 然后以此类推。

#include <bits/stdc++.h>
using namespace std;
long long solve(long long m,int n){
    vector<int> v;
    for(int i=2; i*i<=n; i++){
        if (n % i == 0){
            v.push_back(i);
            while(n % i == 0) n/= i;
        }
    }
    if (n > 1) v.push_back(n);
    long long sum = 0;
    for(int i=1; i< (1 << v.size()); i++){
        int bit = 0; long long mul = 1;
        for(int j=0; j<v.size(); j++){
            if (i & (1 << j)){
                bit++;
                mul *= v[j];
            }
        }
        if (bit & 1) sum += m/mul;
        else sum -= m/mul;
    }
    return m - sum;
}
int main(){
    int T,n;
    long long a,b;
    scanf("%d",&T);
    for(int i=1; i<=T; i++){
        scanf("%lld%lld%d",&a,&b,&n);
        printf("Case #%d: %lld\n",i,solve(b,n) - solve(a-1,n));
    }
    return 0;
}

ACM-ICPC 2018 沈阳赛区网络预赛 G. Spare Tire

打表发现 an 的通项公式为 n*(n+1)
那么 Sn 的通项公式为 n*(n+1)*(2*n+1)/6
那么对于1n 内和 m 互素的数我们可以用上述的容斥原理来求解
例如 m 素数因子 pi 那么对于答案的贡献就是范围内的含有pi因子的数的和

#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
long long  inv[100];
void init(int n){
    inv[1] = 1;
    for(int i = 2; i <=n; i ++)
        inv[i] = (mod - mod / i) * inv[mod % i] % mod;
}
long long cal(long long x,long long N){
    long long n = N/x;
    long long sum = n*(n+1)%mod*(2*n+1)%mod*inv[6]%mod*x % mod * x % mod + n*(n+1)%mod*inv[2] % mod * x%mod;
    return sum % mod;
}
long long solve(long long n,long long m){
    vector<int> v;
    for(int i=2; i*i<=m; i++){
        if (m % i == 0){
            v.push_back(i);
            while(m % i == 0) m/= i;
        }
    }
    if (m > 1) v.push_back(m);
    long long sum = 0;
    for(int i=1; i< (1 << v.size()); i++){
        int bit = 0; long long mul = 1;
        for(int j=0; j<v.size(); j++){
            if (i & (1 << j)){
                bit++;
                mul *= v[j];
        }
        if (bit & 1) {
            sum = (sum + cal(mul,n)) % mod;
        }else{
            sum = (sum + mod - cal(mul,n)) % mod;
        }
    }
    return sum;
}
int main(){
    init(100);
    long long n,m;
    while(scanf("%lld%lld",&n,&m) == 2){
        long long sum1 = cal(1,n);
        printf("%lld\n",(sum1+mod-solve(n, m)) % mod);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
容斥原理是一种计方法,用于解决集合某些对象的目的问题。它的基本思想是先计算包含于某个内容的所有对象的目,然后排除重复计算的对象,以确保计结果既不遗漏又没有重复。在容斥原理的应用,通常需要先求出所有包含的区间,然后使用欧拉函求和,并进行一些补充操作,例如乘以某个系或减去一个常。在使用容斥原理时,需要注意一些细节,例如在枚举因子时要注意使用最小公倍(LCM),而不是直接相乘。如果容斥问题的集合可能包含0,还需要特殊处理。至于如何使用容斥原理在MATLAB求解具体的问题,我需要更多的上下文信息才能给出具体的指导。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [容斥原理](https://blog.csdn.net/ling_wang/article/details/80488797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [容斥原理练习记录](https://blog.csdn.net/z631681297/article/details/81318279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值