RT 线段树解法 但query函数如下面写法时,AC
inline int query(int p, int l, int r, int L, int R) {
if (l > R || r < L)return 0;
if (l >= L && r <= R)return tr[p].sum;
pushdown(p, l, r);
int mid = (l + r) >> 1, ans = 0; //((L <= mid ? : 0)(R > mid ? : 0)
if (L <= mid)(ans += query(ls, l, mid, L, R)) %= mod;
if (R > mid)(ans += query(rs,l,mid, L, R)) %= mod;
return ans;
}
然而,很明显,上面if (R > mid)(ans += query(rs,l,mid, L, R)) %= mod;是错误打法,当其改为正确写法
inline int query(int p, int l, int r, int L, int R) {
if (l > R || r < L)return 0;
if (l >= L && r <= R)return tr[p].sum;
pushdown(p, l, r);
int mid = (l + r) >> 1, ans = 0; //((L <= mid ? : 0)(R > mid ? : 0)
if (L <= mid)(ans += query(ls, l, mid, L, R)) %= mod;
if (R > mid)(ans += query(rs, mid + 1, r, L, R)) %= mod;
return ans;
}
时,会在#8TLE,求助。 全部代码:
#include <bits/stdc++.h>
#define upf(i,n,k) for(int i=k;i<=n;i++)
#define lowf(i,n,k) for(int i=n;i>=k;i--)
#define Max(a,b,c) max(a,max(b,c))
#define Min(a,b,c) min(a,min(b,c))
#define ofile(N) freopen(N".in","r",stdin),freopen(N".out","w",stdout)
#define ri register int
#define ie inline
#define ll long long
#define int long long
#define read() input<int>()
#define rll() input<ll>()
using namespace std;
template<typename T>
ie T input() {
T s = 0, w = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')w = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}
template<typename T>
ie void out(T a) {
if (a < 0)putchar('-'), a = -a;
if (a >= 10)out(a / 10);
putchar(a % 10 + '0');
}
const int mn = 2e6 + 5;
const int mod = 998244353;
struct segTree {
int l, r, mul = 1, add, sum;
} tr[mn << 2];
int tot = 1, n, a[mn], m = 1e9 + 1;
#define ls (tr[(p)].l)
#define rs (tr[(p)].r)
inline void pushup(int p) {
tr[p].sum = (tr[tr[p].l].sum + tr[tr[p].r].sum) % mod;
}
inline void pushdown(int p, int l, int r) {
int mid = (l + r) >> 1;
if (!tr[p].l)tr[p].l = ++tot;
if (!tr[p].r)tr[p].r = ++tot;
tr[ls].sum = (tr[ls].sum * tr[p].mul % mod + tr[p].add * (mid - l + 1) % mod) % mod;
tr[rs].sum = (tr[rs].sum * tr[p].mul % mod + tr[p].add * (r - mid) % mod) % mod;
tr[ls].mul = (tr[ls].mul * tr[p].mul) % mod;
tr[rs].mul = (tr[rs].mul * tr[p].mul) % mod;
tr[ls].add = (tr[ls].add * tr[p].mul % mod + tr[p].add) % mod;
tr[rs].add = (tr[rs].add * tr[p].mul % mod + tr[p].add) % mod;
tr[p].mul = 1, tr[p].add = 0;
}
inline void mul(int p, int l, int r, int L, int R, int k) {
if (l > R || r < L)return;
if (l >= L && r <= R)return (tr[p].sum *= k) %= mod, (tr[p].add *= k) %= mod, (tr[p].mul *= k) %= mod, void();
pushdown(p, l, r);
int mid = (l + r) >> 1;
if (L <= mid)mul(ls, l, mid, L, R, k);
if (R > mid)mul(rs, mid + 1, r, L, R, k);
pushup(p);
}
inline int query(int p, int l, int r, int L, int R) {
if (l > R || r < L)return 0;
if (l >= L && r <= R)return tr[p].sum;
pushdown(p, l, r);
int mid = (l + r) >> 1, ans = 0; //((L <= mid ? : 0)(R > mid ? : 0)
if (L <= mid)(ans += query(ls, l, mid, L, R)) %= mod;
if (R > mid)(ans += query(rs, mid + 1, r, L, R)) %= mod;
return ans;
}
inline void add(int p, int l, int r, int L, int R, int v) {
if (l > R || r < L)return;
if (l >= L && r <= R)return tr[p].sum = (tr[p].sum + v * (r - l + 1) % mod) % mod, tr[p].add = (tr[p].add + v) % mod, void();
pushdown(p, l, r);
int mid = (l + r) >> 1;
if (L <= mid)add(ls, l, mid, L, R, v);
if (R > mid)add(rs, mid + 1, r, L, R, v);
pushup(p);
}
signed main() {
// ofile("sequence");
n = read();
for (ri i = 1; i <= n; i++)a[i] = read();
// if (n == 1)return cout << a[1], 0;
add(1, 1, m, 1, a[1], 1);
for (ri i = 2; i <= n; i++) {
// update(1,1,m,1,a[i],1)
// int s=chi_squared_distribution
int s = query(1, 1, m, 1, a[i - 1] );
mul(1, 1, m, a[i] + 1, m, 0);
mul(1, 1, m, 1, a[i], -1);
add(1, 1, m, 1, a[i], s);
}
printf("%lld", (query(1, 1, m, 1, m) + mod) % mod);
return 0;
}