“玲珑杯” 线上赛Round #17 B 震惊,99%+的中国人都会算错的问题

传送门

__debug神仙计数课件凑系数入门题,我又被锤了。

我们先不考虑奇数的限制,想一下怎么做。是不是可以将任意子集的\(lcm\)进行容斥,算是比较简单的容斥了。

然后我们思考一下,如何通过凑系数来满足奇数的限制。

打表/画韦恩图可知系数为\((-2)^{n-1}\)

首先我们设\(i\)个数对应的系数为\(f[i]\),那么对于一个被\(k\)个数整除的数有:

\[f[k]+\sum_{i=0}^{k}\binom{k}{i}*f[i]=k\ mod\ 2\\ f[k]=(k\ mod\ 2)-\sum_{i=0}^{k}\binom{k}{i}*f[i] \]

其中\(f[1]=1\)

#include<cstdio>
#define ll long long
int t,n,m,a[20];ll ans;
ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
void dfs(int num,ll lcm,int cnt){
    lcm=1LL*lcm*a[num]/gcd(lcm,a[num]);
    if(lcm>n)return ;
    if(cnt&1)ans+=1LL*n/lcm*(1<<(cnt-1));
    else ans-=1LL*n/lcm*(1<<(cnt-1));
    for(int i=num+1;i<=m;i++)dfs(i,lcm,cnt+1);
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);ans=0;
        for(int i=1;i<=m;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)
            dfs(i,a[i],1);
        printf("%lld\n",ans);
    }
}

posted @ 2019-05-04 20:32  努力进步的肥宅yxc  阅读(185)  评论(0编辑  收藏  举报