题解 P7972 【[KSN2021] Self Permutation】
一个显然的结论:对于原序列中的两个位置
据此我们可以设计 dp,设
对于一个位置
树状数组优化 dp 即可。时间复杂度
const int MN = 3e5 + 5, Inf = 1e9, Mod = 1e9 + 7;
int N, A[MN], f[MN], L[MN], R[MN], Ans, st[MN], tp;
struct BIT {
int tr[MN];
inline int lowbit(int x) {
return x & (-x);
}
inline void Modify(int x, int k) {
for (int i = x; i <= N; i += lowbit(i)) {
tr[i] = (tr[i] + k) % Mod;
}
}
inline int Query(int x) {
int res = 0;
for (int i = x; i; i -= lowbit(i)) {
res = (res + tr[i]) % Mod;
}
return res;
}
} T;
signed main(void) {
N = read();
for (int i = 1; i <= N; i++) A[i] = read();
for (int i = 1; i <= N + 1; i++) {
while (tp && A[st[tp]] > A[i]) R[st[tp--]] = i - 1;
st[++tp] = i;
}
for (int i = N; i >= 0; i--) {
while (tp && A[st[tp]] > A[i]) L[st[tp--]] = i + 1;
st[++tp] = i;
}
T.Modify(1, 1);
for (int i = 1; i <= N; i++) {
f[i] = (T.Query(N) - T.Query(L[i] - 1) % Mod + Mod) % Mod;
T.Modify(R[i], f[i]);
}
int mn = Inf;
for (int i = N; i >= 1; i--) {
mn = min(mn, A[i]), Ans = (Ans + (mn == A[i] ? 1 : 0) * f[i]) % Mod;
}
printf("%lld\n", Ans);
return 0;
}