标签:inline 倒序 lin div dig 就是 转换 style 子集
CTSC水题!
做这道题你得了解Lucas定理才行。当模数小的时候,C(n,m)可以转换为Π C(ai,bi),其中ai和bi分别是n和m在mod进制下的每一位。本题mod为2,所以就是二进制下的Π。
你想让连乘大于0,那么所有的都应该等于1.那么对于任意ai,bi,必须有ai>=bi。即b是a的子集,我们只需要倒序递推,每次枚举当前数的子集,答案累加就可以了。至于复杂度,因为ai<=233333,且每个数是唯一的,所以复杂度可以通过。
#include<bits/stdc++.h> using namespace std; const int N=240000; const int mod=1e9+7; int f[N],a[N],n,ans,flag[N]; inline int read(){ char ch=getchar();int num=0,f=1; while(!isdigit(ch)){if(ch==‘-‘) f=-1;ch=getchar();} while(isdigit(ch)){num=(num<<1)+(num<<3)+(ch^48);ch=getchar();} return num*f; } int main(){ n=read(); for(register int i=1;i<=n;++i) a[i]=read(); for(register int i=n;i>0;--i){ flag[a[i]]=1; for(register int j=(a[i]-1)&a[i];j!=0;j=(j-1)&a[i]){ if(!f[j]&&flag[j]) f[a[i]]=(f[a[i]]+1)%mod; else if(f[j]) f[a[i]]=(f[a[i]]+f[j]+1)%mod; } } for(register int i=1;i<=n;++i) ans=(ans+f[a[i]])%mod; printf("%d\n",ans); return 0; }
标签:inline 倒序 lin div dig 就是 转换 style 子集
原文地址:https://www.cnblogs.com/kgxw0430/p/10283275.html