• ACM-ICPC 2018 沈阳赛区网络预赛 G Spare Tire(容斥)


    https://nanti.jisuanke.com/t/31448

    题意

     已知a序列,给你一个n和m求小于n与m互质的数作为a序列的下标的和

    分析

     打表发现ai=i*(i+1)。

    易得前n项和为 Sn=n*(n+1)(2*n+1)/6+n*(n+1)/2;我们直接求与m互质的数较难,所以我们可以换个思路,求与 m不互质的数,那么与m不互质的数,是取m的素因子的乘积(因为根据唯一分解定理,任意个数都可看作的素数积),那么我们将m分解质因数,通过容斥定理,就可以得道与m不互质的数,总和sum减去这些数对应的a的和就是答案了。

    容斥原理的具体如下:

              区间中与i不互质的个数 = (区间中i的每个质因数的倍数个数)-(区间中i的每两个质因数乘积的倍数)+(区间中i的每3个质因数的成绩的倍数个数)-(区间中i的每4个质因数的乘积)+...

             比如存在一个素因子是k,那么需要求下标为k,2k,3k,4k……的a的和,即求(kn)^2+kn通项的求和,为k^2*n*(n+1)*(2n+1)/6+k*n*(n+1)/2,项数为n/k。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn  = 1e4 + 10;
    const int mod = 1e9 + 7;
    ll inv6=166666668;
    ll inv2=500000004;
    ll a[maxn];
    ll cal(ll n,ll x){
        n/=x;
        return (n*(n+1)%mod*(2*n+1)%mod*inv6%mod*x%mod*x%mod+n*(n+1)%mod*inv2%mod*x%mod)%mod;
    }
    int main(){
        ll n,m;
        while(~scanf("%lld%lld",&n,&m)){
            ll tot = cal(n,1);
            int cnt=0;
            for(ll i=2;i*i<=m;i++){
                if(m%i==0){
                    a[cnt++]=i;
                    while(m%i==0) m/=i;
                }
            }
            if(m!=1) a[cnt++]=m;
            ll res=0;
            for(int i=1;i<(1<<cnt);i++){
                ll tmp=1;
                for(int j=0;j<cnt;j++){
                    if((1<<j)&i){
                        tmp=tmp*a[j]%mod;
                    }
                }
                tmp=cal(n,tmp);
                if(__builtin_popcount(i)&1) res=(res+tmp)%mod;
                else res=(res-tmp+mod)%mod;
            }
            printf("%lld
    ",(tot-res+mod)%mod);
        }
        return 0;
    }
  • 相关阅读:
    快速开始
    阿里为什么选择RocketMQ
    4 分布式消息队列的协调者
    9 首个Apache中间件顶级项目
    3、用适合的方式发送和接收消息
    2 生产环境下的配置和使用
    TOMCAT加载两次war包(重复加载)
    Google Protocol Buffer 的使用(二)
    Google Protocol Buffer 的使用(一)
    PostgreSQL及PostGIS使用
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9673313.html
Copyright © 2020-2023  润新知