玄学问题求助
查看原帖
玄学问题求助
148875
NaNO2_Cabbage楼主2023/11/16 15:09

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;
}
2023/11/16 15:09
加载中...