刚刚比赛 D 60pts 求调 /kel
  • 板块学术版
  • 楼主VitrelosTia
  • 当前回复4
  • 已保存回复4
  • 发布时间2024/5/19 13:08
  • 上次更新2024/5/19 13:18:16
查看原帖
刚刚比赛 D 60pts 求调 /kel
672333
VitrelosTia楼主2024/5/19 13:08
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;

const int M = 2e5 + 5, mod = 998244353;
int n, m, Q, l[M], r[M], v[M], s[M], qs[M];
int q(int x) { return x * x % mod; }

signed main() {
//	freopen("Dsample1.in", "r", stdin);
//	freopen("Dout.txt", "w", stdout);
	ios::sync_with_stdio(false); cin.tie(nullptr);
	cin >> n >> m >> Q;
	for (int i = 1; i <= m; i++) cin >> l[i] >> r[i] >> v[i], v[i] %= mod, s[i] = (s[i - 1] + v[i] * (r[i] - l[i] + 1) % mod) % mod, qs[i] = (qs[i - 1] + q(v[i]) * (r[i] - l[i] + 1) % mod) % mod;
//	for (int i = 1; i <= m; i++) printf ("qs[%lld] = %lld\n", i, qs[i]);
	for (int x, y; Q--; ) {
		cin >> x >> y;
		if (x == y) { cout << 0 << '\n'; continue; }
		int lpos = lower_bound(r + 1, r + m + 1, x) - r, rpos = upper_bound(l + 1, l + m + 1, y) - l - 1;
		int sum = (((r[lpos] - x + 1) % mod * v[lpos] % mod + (s[rpos - 1] - s[lpos] + mod) % mod) % mod + (y - l[rpos] + 1) % mod * v[rpos] % mod) % mod;
		int qsum = (((r[lpos] - x + 1) % mod * q(v[lpos]) % mod + (qs[rpos - 1] - qs[lpos] + mod) % mod) % mod + (y - l[rpos] + 1) % mod * q(v[rpos]) % mod) % mod;
		if (lpos == rpos) sum = (y - x + 1) * v[lpos] % mod, qsum = (y - x + 1) * q(v[rpos]) % mod;
//		printf ("(%lld, %lld)\n", lpos, rpos);
//		printf ("sum = %lld, qsum = %lld\n", sum, qsum);
		cout << (qsum * (y - x + 1) % mod - sum * sum % mod + mod) % mod << '\n';
	}
	return 0;
}

思路是对于每个询问,先处理左右散区间,再用前缀和算中间。sum 是和,qsum 是平分和

2024/5/19 13:08
加载中...