一道不难但是拖了很久的题,我这个傻逼活该要退役.
Click here to read the problem.
令
N=log2(maxai)
N
=
l
o
g
2
(
m
a
x
a
i
)
.
网上很多
3N
3
N
的做法,不具体说了,大概就是
dp[x]
d
p
[
x
]
代表以
x
x
结尾的方案数.
考虑分块,把数字二进制下分成前一段和后一段.
设.即前一半为
u
u
,后一半的超集的方案数之和.(超集就是子集的补集).
每加进一个数字,枚举前一半的超集,计算答案;再枚举后一半的子集,因为这个数字结尾的答案将影响后一半子集的 f f 值.
时间复杂度.
#include <bits/stdc++.h>
#define LL long long
using namespace std ;
template <class T> void Read ( T &x, char c = getchar(), bool f = 0 ) {
for ( x = 0 ; !isdigit(c) ; c = getchar() ) f |= c == '-' ;
for ( ; isdigit(c) ; c = getchar() ) x = 10*x + c - '0' ;
if (f) x = -x ;
}
const int maxn = 220000, Mod = 1000000007 ;
int n, m, S, f[520][520] ;
int main() {
int i, x, u, v, val, ans = 0 ;
Read(n) ;
m = 1<<9, S = m-1 ;
for ( i = 1 ; i <= n ; i ++ ) {
Read(x) ;
u = x/m, v = x%m ;
val = 1 ;
for ( x = u^S ; x ; x = (x-1)&(u^S) )
if (f[x|u][v]) (val += f[x|u][v]) %= Mod ;
(val += f[u][v]) %= Mod ;
for ( x = v ; x ; x = (x-1)&v ) (f[u][x] += val) %= Mod ;
(f[u][0] += val) %= Mod ;
}
for ( i = 0 ; i <= S ; i ++ )
(ans += f[i][0]) %= Mod ;
(ans += Mod-n) %= Mod ;
cout << ans << endl ;
return 0 ;
}