各位帅哥看一看吧 明了的线段树 可样例错了
查看原帖
各位帅哥看一看吧 明了的线段树 可样例错了
90972
shitbro楼主2020/6/17 10:58
#include<bits/stdc++.h>
#define MAXN 400005
#define ll long long
using namespace std;
struct node {
	int l,r;
	ll val,add,mul;
}t[MAXN];
int n,m,mod; 
int a[MAXN];
void build(int p,int l,int r) {
	t[p].l = l; t[p].r = r;t[p].val = 0;t[p].mul = 1; 
	if(l == r) {
		t[p].val = a[l]; return ;
	}
	int mid = (l + r) >> 1;
	build(p << 1,l,mid);
	build(p << 1 | 1,mid + 1,r);
	t[p].val = (t[p << 1].val + t[p << 1 | 1].val) % mod; 
}
void spread(int p) {
	t[p << 1].add = (t[p << 1].add * t[p].mul + t[p].add) % mod;
	t[p << 1 | 1].add = (t[p << 1 | 1].add * t[p].mul + t[p].add) % mod;
	t[p << 1].mul = (t[p << 1].mul * t[p].mul) % mod;
	t[p << 1 | 1].mul = (t[p << 1 | 1].mul * t[p].mul) % mod;
	t[p << 1].val = (t[p << 1].val * t[p].mul + t[p << 1].add * (t[p << 1].r - t[p << 1].l + 1)) % mod;
	t[p << 1 | 1].val = (t[p << 1 | 1].val * t[p].mul + t[p << 1 | 1].add * (t[p << 1 | 1].r - t[p << 1 | 1].l + 1)) % mod;
	t[p].add = 0;
	t[p].mul = 1;
}
void mul(int p,int x,int y,ll k) {
	if(t[p].l >= x && t[p].r <= y) {
		t[p].val = (t[p].val * k) % mod;
		t[p].add = (t[p].add * k) % mod;
		t[p].mul = (t[p].mul * k) % mod;
		return ;
	}
	spread(p);
	if((t[p].l + t[p].r) >> 1 >= x) mul(p << 1,x,y,k);
	if((t[p].l + t[p].r) >> 1 < y) mul(p << 1 | 1,x,y,k);
	t[p].val = (t[p << 1].val + t[p << 1 | 1].val) % mod;
}
void add(int p,int x,int y,ll k) {
	if(t[p].l >= x && t[p].r <= y) {
		t[p].val = (t[p].val + (t[p].r - t[p].l + 1) * k) % mod;
		t[p].add = (t[p].add + k) % mod;
		return ;
	}
	spread(p);
	if(((t[p].l + t[p].r) >> 1) >= x) add(p << 1,x,y,k);
	if(((t[p].l + t[p].r) >> 1) < y) add(p << 1 | 1,x,y,k);
	t[p].val = (t[p << 1].val + t[p << 1 | 1].val) % mod; 
}
ll query(int p,int x,int y) {
	if(t[p].l >= x && t[p].r <= y) return t[p].val;
	spread(p);
	ll ans = 0;
	if(((t[p].l + t[p].r) >> 1) >= x) ans = (ans + query(p << 1,x,y)) % mod;
	if(((t[p].l + t[p].r) >> 1) < y) ans = (ans + query(p << 1 | 1,x,y)) % mod;
	return ans % mod;
}
int main()
{
	scanf("%d%d%lld",&n,&m,&mod);
	for(int i = 1;i <= n;i ++) {
		scanf("%d",&a[i]);
	}
	build(1,1,n); 
	for(int i = 1;i <= m;i ++) {
		int opt;
		scanf("%d",&opt);
		int x,y;
		ll k;
		if(opt == 1) {
			scanf("%d%d%lld",&x,&y,&k);
			mul(1,x,y,k);
		}
		else if(opt == 2) {
			scanf("%d%d%lld",&x,&y,&k);
			add(1,x,y,k);
		}
		else {
			scanf("%d%d",&x,&y);
			printf("%lld\n",query(1,x,y));
		}
	}
	return 0;
}
2020/6/17 10:58
加载中...