P8434 「WHOI-2」D&D
P8434 「WHOI-2」D&D
集合
考虑原序列的装饰子集
考虑
这证明了所有子串装饰子集等于
令
容易得到 DP
求
时间复杂度
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
bool Mbe;
constexpr int N = 3e6 + 5;
constexpr int mod = 1e9 + 7;
void add(int &x, int y) {x += y, x >= mod && (x -= mod);}
int n, a[N], f[N], g[N], s[N], cnt, buc[N], exist[N];
bool Med;
int main() {
fprintf(stderr, "%.4lf\n", (&Mbe - &Med) / 1048576.0);
#ifdef ALEX_WEI
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
ios::sync_with_stdio(0);
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i], f[a[i]] = exist[a[i]] = 1;
for(int d = 2, k = 1; k < 1 << 21; d <<= 1, k <<= 1)
for(int i = 0; i < 1 << 21; i += d)
for(int j = 0; j < k; j++)
f[i | j] += f[i | j | k];
for(int i = 0; i < 1 << 21; i++) cnt += f[i] == 1 && exist[i];
g[0] = s[0] = 1;
for(int i = 1, l = 1; i <= n; i++) {
s[i] = s[i - 1];
cnt -= !buc[a[i]] && f[a[i]] == 1;
buc[a[i]]++;
while(f[a[l]] != 1 || buc[a[l]] > 1) buc[a[l++]]--;
if(!cnt) g[i] = s[l - 1];
add(s[i], g[i]);
}
cout << g[n] << "\n";
return cerr << "Time: " << clock() << "\n", 0;
}