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

[luogu 3773][CTSC 2017]吉夫特

时间:2018-11-26 02:36:33      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:def   rac   define   开始   答案   etc   写博客   www   复杂度   

?传送门?

Solution

输入一个长度为n的数列,求有多少个长度大等于2的不上升子序列满足:

\[\prod_{i=2}^{k} C(a_{b_{i-1}},a_{b_i}) mod\ 2 >0 \]

答案对1e9+7取模

根据Lucas定理:

\[C\ (n,\ m)\ ≡\ C\ (\frac{n}{p},\frac{m}{p})*\ C\ (n\%p,\ m\%p)\ (mod\ p)\]

可以发现,只要满足m是n的子集,或者说是(n&m)=m即可。

f[i]表示从\(a_i\)开始的序列的数量,转移时枚举 \(a_i\)的子集,要判断一下它出现的位置是否在i之后

因为我们的\(a_i\)时互不相同的,所以,复杂度大概是\(O(3^{\log \max a_i})\)

写博客的真实原因其实是,pac弱到连枚举子集都不会



#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define swap(x,y) (x^=y^=x^=y)
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
#define MN 211990
#define MM 233335
#define mod 1000000007
int a[MN],pos[MM],f[MN];
int n,ans;
inline void add(int &x,int y){x+=y;x>=mod?x-=mod:0;}
int main()
{
    n=read();
    register int i,j;
    for(i=1;i<=n;++i) a[i]=read(),pos[a[i]]=i;
    for(i=n;i;--i)
    {
        f[i]=1;
        for(j=a[i]&(a[i]-1);j;j=a[i]&(j-1))
            if(pos[j]>i) add(f[i],f[pos[j]]);
        add(ans,f[i]);
    }
    add(ans,mod-n);
    printf("%d\n",ans);
    return 0;
}


所以呢,如何枚举子集?

for(i=S;i&=S;--i)




Blog来自PaperCloud,未经允许,请勿转载,TKS!

[luogu 3773][CTSC 2017]吉夫特

标签:def   rac   define   开始   答案   etc   写博客   www   复杂度   

原文地址:https://www.cnblogs.com/PaperCloud/p/10018111.html

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