#300. 【CTSC2017】吉夫特

来源:互联网 发布:iis批量绑定域名 编辑:程序博客网 时间:2024/06/06 05:21

明明已经广为流传,bzoj就是不贴题面
uoj题面传送门吉夫特

考虑Cmn mod 21的成立条件
根据Lucas定理,有Cmn mod 2=Cm2n2Cm mod 2n mod 2
那么如果这个东西最后等于0,一定存在某一位,m在这一位上为1n0
因为C10不存在的
那么就能证明,当n & m = m时Cmn mod 21
那么记f[i]为以数字i结尾的合法方案数
枚举子集转移就行了
O(3N)其中N为最大幂次

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn = 2E5 + 4E4 + 233;const int mo = 1000000007;int n,A[maxn],f[maxn],pos[maxn];#define Add(x,y) ((x) + (y) < mo ? (x) + (y) : (x) + (y) - mo)#define Dec(x,y) ((x) - (y) >= 0 ? (x) - (y) : (x) - (y) + mo)inline int getint(){    char ch = getchar(); int ret = 0;    while (ch < '0' || '9' < ch) ch = getchar();    while ('0' <= ch && ch <= '9')        ret = ret * 10 + ch - '0',ch = getchar();    return ret;}int main(){    #ifdef DMC        freopen("DMC.txt","r",stdin);    #endif    n = getint();    for (int i = 1; i <= n; i++)        A[i] = getint(),pos[A[i]] = i,f[A[i]] = 1;    for (int i = 1; i <= n; i++)        for (int o = A[i] - 1 & A[i]; o; o = o - 1 & A[i])            if (pos[o] > i) f[o] = Add(f[o],f[A[i]]);    int Ans = 0;    for (int i = 1; i <= n; i++)        Ans = Add(Ans,f[A[i]]);    cout << Dec(Ans,n) << endl;    return 0;}
原创粉丝点击