1. 程式人生 > >“玲瓏杯” 線上賽Round #17 B 震驚,99%+的中國人都會算錯的問題

“玲瓏杯” 線上賽Round #17 B 震驚,99%+的中國人都會算錯的問題

fine 入門 限制 return scan num del bug 簡單的

傳送門

__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);
    }
}

“玲瓏杯” 線上賽Round #17 B 震驚,99%+的中國人都會算錯的問題