思路很巧妙的一道题 ~
这个应该不完全是正解,复杂度约为 $O(3 imes 10^8)$,有时间再研究研究正解.
首先,最裸的暴力是按照权值从小到大枚举每一个数,然后枚举后面的数来更新方案数,是 $O(n^2)$ 的.
然后,我们可以用lucas定理来模拟那个组合数,会发现只需满足大数&小数=小数即可.
这个的话可以枚举子集,复杂度就是 $O(3^{18})$ 左右的,大概能过 ~
code:
#include <bits/stdc++.h> #define ll long long #define N 300000 #define MAX 233333 #define mod 1000000007 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int f[N],pos[N]; int main() { // setIO("input"); int i,j,n,ans=0; scanf("%d",&n); for(i=1;i<=n;++i) { int x; scanf("%d",&x); pos[x]=i; } for(i=1;i<=233333;++i) { if(pos[i]) { for(j=i&(i-1);j;j=i&(j-1)) { if(pos[j]>pos[i]) { f[i]=(f[i]+f[j]+1)%mod; } } } } for(i=1;i<=233333;++i) ans=(ans+f[i])%mod; printf("%d ",ans); return 0; }