loj6356 四色灯

传送门

分析

见ymh大爷博客

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define _thec (c[i][0]+c[i][4]+c[i][8]+c[i][12]+c[i][16]+c[i][20])
#define int long long
const int mod = 998244353;
int a[110],f[110],g[110],c[110][110];
inline void getc(){
    int i,j;
    for(i=0;i<=100;i++)c[i][0]=c[i][i]=1;
    for(i=0;i<=100;i++)
      for(j=1;j<i;j++)
        c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
inline int gcd(int x,int y){return y?gcd(y,x%y):x;}
inline int pw(int x,int p){
    int res=1;
    while(p){
      if(p&1)res=res*x%mod;
      x=x*x%mod;
      p>>=1;
    }
    return res;
}
signed main(){
    int n,m,i,j,k;
    scanf("%lld%lld",&n,&m);
    for(i=0;i<m;i++)scanf("%lld",&a[i]);
    getc();
    for(i=0;i<(1<<m);i++){
      int cnt=0,lcm=1;
      for(j=0;j<m;j++)if((1<<j)&i){
          lcm=lcm/gcd(lcm,a[j])*a[j];
          if(lcm>n)break;
          cnt++;
      }
      if(lcm>n)continue;
      f[cnt]=(f[cnt]+n/lcm)%mod;
    }
    for(i=0;i<=m;i++)g[i]=f[i];
    for(i=m;i>=0;i--)
      for(j=i+1;j<=m;j++)
        g[i]=(g[i]-g[j]*c[j][i]%mod+mod)%mod;
    int Ans=0;
    for(i=0;i<=m;i++)
      Ans=(Ans+g[i]*pw(2,m-i)%mod*_thec%mod)%mod;
    printf("%lld
",Ans*pw(pw(2,m),mod-2)%mod);
    return 0;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/10088613.html