码迷,mamicode.com
首页 > 其他好文 > 详细

【CTSC2017】吉夫特

时间:2019-01-17 17:52:09      阅读:169      评论:0      收藏:0      [点我收藏+]

标签: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;
}

 

【CTSC2017】吉夫特

标签:inline   倒序   lin   div   dig   就是   转换   style   子集   

原文地址:https://www.cnblogs.com/kgxw0430/p/10283275.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!