序列
a
1
,
a
2
,
⋯
,
a
n
a_1,a_2,\cdots ,a_n
a1,a2,⋯,an,求子序列中长度大于1的传奇序列的个数。
1
≤
n
≤
3
∗
1
0
5
,
0
≤
a
i
<
2
18
1\leq n \leq 3*10^5, 0\leq a_i < 2^{18}
1≤n≤3∗105,0≤ai<218,结果对100000007取余。
若序列
b
1
,
b
2
,
⋯
,
b
k
b_1,b_2,\cdots ,b_k
b1,b2,⋯,bk 满足
b
i
&
b
j
=
b
j
且
i
<
j
b_i\; \&\; b_j = b_j \;且\;i<j
bi&bj=bj且i<j ,则称为传奇序列。
分析
遍历子序列的一般方式:将子序列按结尾元素分成子空间,子空间数量
O
(
n
)
O(n)
O(n);
&
\&
& 运算性质
a
&
b
=
b
a\; \&\; b = b
a&b=b,例如:
a
=
1110
1010
,
b
=
1100
0010
a = 1110\;1010,b = 1100\; 0010
a=11101010,b=11000010
若
a
&
b
=
b
,
b
&
c
=
c
a\; \&\; b = b,b\; \&\; c = c
a&b=b,b&c=c,那么
a
&
c
=
c
a\; \&\; c = c
a&c=c
小于
a
a
a 的最大
b
=
(
a
−
1
)
&
a
b = (a-1)\;\&\;a
b=(a−1)&a,递推式
b
i
+
1
=
(
b
i
−
1
)
&
a
(
b
i
>
b
i
+
1
)
b_{i+1} = (b_i-1)\;\&\;a\quad(b_i > b_{i+1})
bi+1=(bi−1)&a(bi>bi+1)
大于
b
b
b 的最小
a
=
(
b
+
1
)
∥
a
a = (b+1)\;\|\;a
a=(b+1)∥a,递推式
a
i
+
1
=
(
a
i
+
1
)
∥
a
(
a
i
<
a
i
+
1
)
a_{i+1} = (a_i+1)\;\|\;a\quad(a_i < a_{i+1})
ai+1=(ai+1)∥a(ai<ai+1)
暴力枚举
分析
设
f
[
i
]
f[i]
f[i] 是以元素
a
i
a_i
ai 结尾的的满足条件的子序列的数量(元素下标:
i
i
i )
设
g
[
a
]
g[a]
g[a] 是以元素
a
a
a 结尾的的满足条件的子序列的数量(元素值:
a
a
a )
则递推过程
到哪里去?
g
[
a
]
g[a]
g[a] 定义:能与值为
a
a
a 的元素构成传奇序列的子序列数量
f
[
i
]
=
g
[
a
i
]
+
1
f[i] = g[a_i]+1
f[i]=g[ai]+1
g
[
a
j
]
=
g
[
a
j
]
+
f
[
i
]
g[a_j] = g[a_j] +f[i]
g[aj]=g[aj]+f[i],其中
j
∈
{
i
,
i
+
k
1
,
i
+
k
2
,
⋯
}
,
a
i
&
a
j
=
a
j
j \in \{i,i+k_1,i+k_2,\cdots \},a_i \;\&\;a_j=a_j
j∈{i,i+k1,i+k2,⋯},ai&aj=aj,复杂度
O
(
n
)
O(n)
O(n)
可优化:序列的后续元素中可能不出现值为
a
j
a_j
aj 的元素,能延迟或不操作更佳;依据查询的“组合”策略,进行组合内修改
从哪里来?
g
[
a
]
g[a]
g[a] 定义:尾元素值为
a
a
a 的传奇数列数量
f
[
i
]
=
∑
k
g
[
a
k
]
f[i] = \sum_k g[a_k]
f[i]=∑kg[ak],其中
1
≤
k
≤
i
−
1
,
a
k
&
a
i
=
a
i
1 \leq k \leq i-1,a_k \;\&\;a_i=a_i
1≤k≤i−1,ak&ai=ai,复杂度
O
(
n
)
O(n)
O(n)
g
[
a
i
]
=
g
[
a
i
]
+
f
[
i
]
g[a_i] = g[a_i] +f[i]
g[ai]=g[ai]+f[i]
可优化:某些数据可能被反复查询而且是可以成为一个固定的组合(前缀和就是一种组合)
无论是哪种递推方式,复杂度都为:
O
(
n
2
)
O(n^2)
O(n2)
混合递推+前缀和
分析
对暴力枚举进行优化
递推方法:" 到哪里去?“和"从哪里来?” 相结合
f
[
i
]
f[i]
f[i] 定义不变,即以元素
a
i
a_i
ai 结尾的的满足条件的子序列的数量(元素下标:
i
i
i )
g
[
a
]
⇒
g
[
A
]
[
B
]
g[a] \Rightarrow g[A][B]
g[a]⇒g[A][B] ,
A
、
B
A、B
A、B 分别等于元素值
a
a
a 的高9位和低9位
g
[
A
]
[
B
]
=
∑
f
[
i
]
g[A][B] = \sum f[i]
g[A][B]=∑f[i],其中
a
[
i
]
=
(
A
<
<
9
)
+
B
k
,
B
k
&
B
=
B
a[i] = (A<<9) +B_k,B_k \;\&\;B=B
a[i]=(A<<9)+Bk,Bk&B=B
类似于是一个前缀和或后缀和, 以153629为例,则
B
k
∈
{
29
,
31
,
⋯
,
509
,
511
}
B_k \in \{29,31,\cdots,509,511\}
Bk∈{29,31,⋯,509,511}
设
A
=
a
i
>
>
9
,
B
=
a
i
&
511
A = a_i >> 9, B = a_i\; \&\;511
A=ai>>9,B=ai&511
f
[
i
]
=
∑
j
=
1
k
g
[
A
j
]
[
B
]
+
1
f[i] =\sum_{j = 1}^k g[A_j][B]+1
f[i]=∑j=1kg[Aj][B]+1,其中
A
=
A
1
<
⋯
<
A
k
≤
511
,
A
j
&
A
=
A
A = A_1 < \cdots < A_k \leq 511,A_j\; \&\; A = A
A=A1<⋯<Ak≤511,Aj&A=A,复杂度
O
(
n
)
O(\sqrt{n})
O(n),【从哪里来?】
g
[
A
]
[
B
j
]
=
g
[
A
]
[
B
j
]
+
f
[
i
]
g[A][B_j] =g[A][B_j] +f[i]
g[A][Bj]=g[A][Bj]+f[i],其中
B
=
B
1
>
⋯
>
B
k
≥
0
,
B
&
B
j
=
B
j
B = B_1 > \cdots > B_k \geq 0,B\; \&\; B_j = B_j
B=B1>⋯>Bk≥0,B&Bj=Bj,复杂度
O
(
n
)
O(\sqrt{n})
O(n),【到哪里去?】
复杂度:
O
(
n
n
)
O(n\sqrt{n})
O(nn)
代码
#include<bits/stdc++.h>usingnamespace std;#defineMD1000000007int n, a, g[520][520], ans;intmain(){int t, x, y, cur;scanf("%d",&t);while(t--){scanf("%d",&n);memset(g,0,sizeof g);
ans =0;for(int i =1; i <= n;++i){scanf("%d",&a);
x = a>>9, y = a&511, cur =1;for(int j = x; j <=511; j =(j+1)|x)
cur =(cur + g[j][y])% MD;// cur: f[i]
ans =(ans + cur)%MD;for(int j = y;; j =(j-1)&y){
g[x][j]=(g[x][j]+ cur)%MD;if(j ==0)break;}}printf("%d\n", ans-n>0?(ans-n):(ans-n+MD));}return0;}