T了
查看原帖
T了
537520
DESTRUCTION_3_2_1楼主2022/12/1 23:05
// Problem: P3373 【模板】线段树 2
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3373
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define int __int128
#define double long double
#define RE register
#define endl putchar('\n')
#define mp make_pair
#define pr pair < int , int >
#define It iterator
#define NF string::npos // NT --> NOT_FOUND
#define swap(x, y) (x ^= y ^= x ^= y)
#define max(x, y) (x > y ? x : y)
#define min(x, y) (x < y ? x : y)
#define ls (p << 1)  // x * 2
#define rs (p << 1 | 1) // x * 2 + 1
using namespace std;
const int INF = 2147483647;
const int SZ = 1e5 + 5;
int n, m, mod, sum[SZ << 2], mul[SZ << 2], tag[SZ << 2], a[SZ], l, r, k, opt;
// 变量
inline int read() {
	RE int X=0,w=0; RE char ch=0;
	while (!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
	while (isdigit(ch)) { X = (X << 3) + (X << 1) + (ch ^ 48); ch = getchar(); }
	return w ? -X : X; }
inline void write(int x) {
	if (x < 0) { x = ~x + 1; putchar('-'); }
	if(x > 9) write(x / 10);
	putchar(x % 10 + '0'); }
// 函数
inline void pushUp (int p) {
	sum[p] = sum[ls] + sum[rs];
	sum[p] %= mod;
}
inline void pushDown (int p, int s, int t) {
	int mid = s + ((t - s) >> 1);
	if (mul[p] != 1) {
		// *
		mul[ls] *= mul[p]; mul[rs] *= mul[p];
		sum[ls] *= mul[p]; sum[rs] *= mul[p];
		tag[ls] *= mul[p]; tag[rs] *= mul[p];
		// %
		mul[ls] %= mod; mul[rs] %= mod;
		sum[ls] %= mod; sum[rs] %= mod;
		tag[ls] %= mod; tag[rs] %= mod;
		mul[p] = 1;
	}
	if (tag[p]) {
		// +
		sum[ls] += tag[p] * (mid - s + 1); sum[rs] += tag[p] * (t - mid);
		tag[ls] += tag[p]; tag[rs] += tag[p];
		// %
		sum[ls] %= mod; sum[rs] %= mod;
		tag[ls] %= mod; tag[rs] %= mod;
		tag[p] = 0;
	}
}
inline void build (int p, int s, int t) {
	mul[p] = 1;
	if (s == t) {
		sum[p] = a[s];
		return;
	}
	int mid = s + ((t - s) >> 1);
	build(ls, s, mid);
	build(rs, mid + 1, t);
	pushUp(p);
}
inline void add_mul (int p, int l, int r, int s, int t, int k) {
	if (l <= s && t <= s) {
		mul[p] *= k; sum[p] *= k; tag[p] *= k;
		mul[p] %= mod; sum[p] %= mod; tag[p] %= mod;
		return;
	}
	pushDown(p, s, t);
	int mid = s + ((t - s) >> 1);
	if (mid >= l) add_mul (ls, l, r, s, mid, k);
	if (mid + 1 <= r) add_mul (rs, l, r, mid + 1, t, k);
	pushUp(p);
}
inline void add_sum (int p, int l, int r, int s, int t, int k) {
	if (l <= s && t <= r) {
		tag[p] += k; tag[p] %= mod;
		sum[p] += k * (t - s + 1); sum[p] %= mod;
		return;
	}
	pushDown(p, s, t);
	int mid = s + ((t - s) >> 1);
	if (mid >= l) add_sum (ls, l, r, s, mid, k);
	if (mid + 1 <= r) add_sum (rs, l, r, mid + 1, t, k);
	pushUp(p);
}
inline int getans (int p, int l, int r, int s, int t) {
	if (l <= s && t <= r) return sum[p];
	pushDown(p, s, t);
	int mid = s + ((t - s) >> 1), ans = 0;
	if (mid >= l) ans += getans(ls, l, r, s, mid);
	if (mid + 1 <= r) ans += getans(rs, l, r, mid + 1, t);
	return ans % mod;
}
signed main(void)
{
	//freopen("input.in","r",stdin);
	//freopen("output.out","w",stdout);
	n = read(); m = read(); mod = read();
	for (int i = 1; i <= n; i++) a[i] = read();
	build(1, 1, n);
	for (int i = 1; i <= m; i++) {
		opt = read();
		if (opt == 1) {
			l = read(); r = read(); k = read();
			add_mul(1, l, r, 1, n, k);
		}
		if (opt == 2) {
			l = read(); r = read(); k = read();
			add_sum(1, l, r, 1, n, k);
		}
		if (opt == 3) {
			l = read(); r = read();
			write(getans(1, l, r, 1, n));
			endl;
		}
	}
	//fclose(stdin);
	//fclose(stdout);
	return 0;
}

1.为什么会T

2.求取余时间复杂

2022/12/1 23:05
加载中...