求助,连样例都没过
查看原帖
求助,连样例都没过
363006
wangyibo201026楼主2022/1/19 14:47

众所周知,线段树是非常难调的,所以,求助 daolao:

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 4e5 + 5;

int n, m, p;
int d[N], l1[N], l2[N], a[N];

void F(int node, int l, int r, int add, int mul){
	d[node] = ((r - l + 1) * add % p + d[node] * mul % p) % p;
	l2[node] = l2[node] % p * mul % p;
	l1[node] = (add + l1[node] * mul % p) % p;
}

void push_up(int node){
	d[node] = (d[node << 1] % p + d[(node << 1) + 1] % p) % p;
}

void push_down(int l, int r, int node){
	int mid = l + r >> 1;
	F(node << 1, l, mid, l1[node], l2[node]);
	F((node << 1) + 1, mid + 1, r, l1[node], l2[node]);
	l1[node] = 0;
	l2[node] = 1;
}

void build(int l, int r, int node){
	l2[node] = 1;
	l1[node] = 0;
	if(l == r){
		d[node] = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build(l, mid, node << 1);
	build(mid + 1, r, (node << 1) + 1);
	push_up(node);
}

void update(int l, int r, int s, int t, int node, int add, int mul){
	if(l <= s && t <= r){
		F(node, s, t, add, mul);
		return ;
	}
	push_down(s, t, node);
	int mid = s + t >> 1;
	if(l <= mid){
		update(l, r, s, mid, node << 1, add, mul);
	}
	if(mid + 1 <= mid){
		update(l, r, mid + 1, t, (node << 1) + 1, add, mul);
	}
	push_up(node);
}

int query(int l, int r, int s, int t, int node){
	if(l <= s && t <= r){
		return d[node] % p;
	}
	push_down(s, t, node);
	int sum = 0, mid = s + t >> 1;
	if(l <= mid){
		sum += query(l, r, s, mid, node << 1);
		sum %= p;
	}
	if(mid + 1 <= r){
		sum += query(l, r, mid + 1, t, (node << 1) + 1);
		sum %= p;
	}
	return sum % p;
}

signed main(){
	cin >> n >> m >> p;
	for(int i = 1; i <= n; i++){
		cin >> a[i];
	}
	build(1, n, 1);
	while(m--){
		int op;
		cin >> op;
		if(op == 1){
			int x, y, k;
			cin >> x >> y >> k;
			update(x, y, 1, n, 1, 0, k);
		}
		else if(op == 2){
			int x, y, k;
			cin >> x >> y >> k;
			update(x, y, 1, n, 1, k, 1);
		}
		else{
			int x, y;
			cin >> x >> y;
			cout << query(x, y, 1, n, 1) % p << endl;
		}
	}
	return 0;
}
2022/1/19 14:47
加载中...