zoukankan      html  css  js  c++  java
  • NOIP 模拟 $88; m 按位或$

    题解 (by;zjvarphi)

    (t) 的所有子集中为 (3) 的倍数的数的个数为 (m) ,那么总方案数就是 (m^n)

    考虑容斥减掉所有不合法的情况,二项式反演推一下:

    (f_i) 为至多有 (i) 位为 (1)(g_i) 表示恰好有 (i) 位为 (1)(其中 (i) 位都是具体的 (i) 位,不是单指数量),则有:

    [f_n=sum_{i=0}^ninom{n}{i}g_i\ g_n=sum_{i=0}^n(-1)^{n-i}inom{n}{i}f_i ]

    答案就是 (g_n),问题变为如何求 (f_i)

    一种方案是暴力枚举哪些位为 (1),但是复杂度就成了 (mathcal{O m(n)})

    发现每一位 (mod 3) 只可能是 (2)(1),那么只需要知道留下的位中有多少个 (mod 3)(1) 的,为 (2) 的即可。

    实现的时候枚举选了多少位,其中多少个为 (1) 的,多少个为 (2) 的,求方案数用一个背包,最后乘上组合数。

    其实求的不是 (f_i),而是 (inom{n}{i}f_i),所以最后直接按着容斥系数加上即可。

    复杂度 (mathcal{O m(log^2t imes logn)})

    Code
    #include<bits/stdc++.h>
    #define ri signed
    #define pd(i) ++i
    #define bq(i) --i
    #define func(x) std::function<x>
    namespace IO{
        char buf[1<<21],*p1=buf,*p2=buf;
        #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++
        #define debug1(x) std::cerr << #x"=" << x << ' '
        #define debug2(x) std::cerr << #x"=" << x << std::endl
        #define Debug(x) assert(x)
        struct nanfeng_stream{
            template<typename T>inline nanfeng_stream &operator>>(T &x) {
                bool f=false;x=0;char ch=gc();
                while(!isdigit(ch)) f|=ch=='-',ch=gc();
                while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc();
                return x=f?-x:x,*this;
            }
        }cin;
    }
    using IO::cin;
    namespace nanfeng{
        #define FI FILE *IN
        #define FO FILE *OUT
        template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
        template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
        using ll=long long;
        static const int MOD=998244353;
        int C[65][65],nm,nm1,nm2;
        ll dp[2][3],n,t,ans;
        auto fpow=[](ll x,int y) {
            ll res=1;
            while(y) {
                if (y&1) res=res*x%MOD;
                x=x*x%MOD;
                y>>=1;
            }
            return res;
        };
        auto calc=[](int a,int b) {
            memset(dp,0,sizeof(dp));
            int nw=0;
            dp[0][0]=1;
            for (ri i(1);i<=a;pd(i)) {
                int cur=nw^1;
                memcpy(dp[cur],dp[nw],sizeof(dp[nw]));
                for (ri j(0);j<3;pd(j)) (dp[cur][(j+1)%3]+=dp[nw][j])%=MOD;
                nw=cur;
            }
            for (ri i(1);i<=b;pd(i)) {
                int cur=nw^1;
                memcpy(dp[cur],dp[nw],sizeof(dp[nw]));
                for (ri j(0);j<3;pd(j)) (dp[cur][(j+2)%3]+=dp[nw][j])%=MOD;
                nw=cur;
            }
            return dp[nw][0];
        };
        inline int main() {
            FI=freopen("or.in","r",stdin);
            FO=freopen("or.out","w",stdout);
            cin >> n >> t;
            C[0][0]=1;
            for (ri i(1);i<=60;pd(i)) {
                C[i][0]=1;
                for (ri j(1);j<=60;pd(j)) C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
            }
            for (ri i(0);i<=60;pd(i)) 
                if (t>>i&1ll) {
                    ++nm;
                    if (i&1) ++nm2;else ++nm1;
                }
            int ln=n%(MOD-1);
            for (ri i(0),f(1);i<=nm;pd(i),f=-f) {
                int lim=cmin(i,nm1);
                for (ri j(0);j<=lim;pd(j)) {
                    if (i-j>nm2) continue;
                    ans+=f*fpow(calc(nm1-j,nm2-i+j),ln)*C[nm1][j]%MOD*C[nm2][i-j]%MOD;
                }
            }
            printf("%lld
    ",(ans%MOD+MOD)%MOD);
            return 0;
        }
    }
    int main() {return nanfeng::main();}
    
  • 相关阅读:
    ASP.NET CORE 使用Consul实现服务治理与健康检查(2)——源码篇
    ASP.NET CORE 使用Consul实现服务治理与健康检查(1)——概念篇
    Asp.Net Core 单元测试正确姿势
    如何通过 Docker 部署 Logstash 同步 Mysql 数据库数据到 ElasticSearch
    Asp.Net Core2.2 源码阅读系列——控制台日志源码解析
    使用VS Code 开发.NET CORE 程序指南
    .NetCore下ES查询驱动 PlainElastic .Net 升级官方驱动 Elasticsearch .Net
    重新认识 async/await 语法糖
    EF添加
    EF修改部分字段
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15500985.html
Copyright © 2011-2022 走看看