• [luogu5387]人形演舞


    先对每一个求sg函数,暴力复杂度为$o(m^{2})$

    取$k$满足$2^{k}le x<2^{k+1}$(即$x$二进制下的最高位),考虑$y$与$2^{k}$的关系

    1.若$1le y<2^{k}$,那么必然有$1le yle x$,因此仅要求$0le (xoplus y)<x$

    由于$y$的第$k$位为0且$x$的第$k$位为1,因此$2^{k}le (xoplus y)<x$,同时对于其中任意一个取值,根据异或的可逆性,都可以得到

    2.若$2^{k}le yle x$,类似的必然有$0le (xoplus y)le x-2^{k}$,同样其中任意一个取值都可以得到

    换言之,$x$的后继的范围为$[0,x-2^{k}]cup[2^{k},x)$,归纳$sg(x)=x-2^{k}+1$,则$sg(2^{k})=1$(其后继只有$sg(0)=0$),然后$sg(x)=mex(sg(0),sg([2^{k},x]))ge x-2^{k}+1$

    同时,由于$sg(x)le x$,因此前面半段不能增加答案,即得到结论

    进一步的,即求$sum_{igoplus_{i=1}^{n}sg(a_{i})=0}1$,令$f_{n}(x)=sum_{i=0}^{infty}(sum_{igoplus_{j=1}^{n}sg(a_{j})=i}1)x^{i}$,定义乘法为两式的异或卷积,即有$f_{n}(x)=f_{n-1}(x)f_{1}(x)=f^{n}_{1}(x)$,用快速幂+FWT计算,时间复杂度为$o(mlog_{2}nlog_{2}m)$

    然后注意到FWT和IFWT的执行,在快速幂中存在重复,因此只需要在最开始和结尾执行一次,时间复杂度降为$o(m(log_{2}mod+log_{2}m))$,即可通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 998244353
     4 int n,ans,f[2000005];
     5 long long m;
     6 int main(){
     7     scanf("%lld%d",&m,&n);
     8     m%=mod-1;
     9     for(int i=0;i<20;i++)
    10         for(int j=(1<<i);j<=min((1<<i+1)-1,n);j++)f[j-(1<<i)+1]++;
    11     for(int i=0;i<20;i++)
    12         for(int j=0;j<(1<<20);j++)
    13             if (j&(1<<i)){
    14                 int x=f[j],y=f[(j^(1<<i))];
    15                 f[(j^(1<<i))]=(x+y)%mod;
    16                 f[j]=(y+mod-x)%mod;
    17             }
    18     for(int i=0;i<(1<<20);i++){
    19         int x=f[i],y=m;
    20         f[i]=1;
    21         while (y){
    22             if (y&1)f[i]=1LL*f[i]*x%mod;
    23             x=1LL*x*x%mod;
    24             y>>=1;
    25         }
    26     }
    27     for(int i=0;i<20;i++)
    28         for(int j=0;j<(1<<20);j++)
    29             if (j&(1<<i)){
    30                 int x=f[j],y=f[(j^(1<<i))];
    31                 f[(j^(1<<i))]=1LL*(mod+1)/2*(x+y)%mod;
    32                 f[j]=1LL*(mod+1)/2*(y+mod-x)%mod;
    33             }
    34     for(int i=1;i<(1<<20);i++)ans=(ans+f[i])%mod;
    35     printf("%d",ans);
    36 }
    View Code
  • 相关阅读:
    arm-linux-gcc编译时出现stray '357''273' '277' in program的解决方法
    C#中dynamic的正确用法
    C# 利用反射调用类下的方法
    C# 如何利用反射,将字符串转化为类名并调用类中方法
    将string转为同名类名,方法名。(c#反射)
    MethodInfo类的一般使用
    easyUi弹出window窗口传值与调用父页面的方法,子页面给父页面赋值
    [收集] 各式各样的 无限级分类 的数据库设计方案
    JavaScript随机生成信用卡卡号的方法
    C#中Invoke的用法
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14036172.html
Copyright © 2020-2023  润新知