下放操作乘法是用!=1判定的,还是30分
查看原帖
下放操作乘法是用!=1判定的,还是30分
1165228
o_CIHL楼主2024/11/7 01:35
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+11;

int n, m, a[N], PP;
struct aaa{
	int l, r, d, dd, dx;
}t[N*4+11];


void makke(int p, int l, int r){
	t[p].l = l; t[p].r = r;
	if(l == r){
		t[p].dx = 1;
		t[p].d = a[l];
		return ;
	}
	
	int mid = l + r >> 1;
	int x = p << 1, y = p << 1 | 1;
	makke(x, l, mid); makke(y, mid + 1, r);
	t[p].d = t[x].d + t[y].d;
	t[p].d %= PP; t[p].dx = 1;
}

void don(int p){ // 先乘法后加法,
	//并且我们此处的加法dd是如果有乘法的话,这里的dd也是乘之后的 
	int x = p << 1, y = p << 1 | 1;
	
	if(t[p].dx != 1){
		t[x].dx *= t[p].dx; t[x].dx %= PP;
		t[y].dx *= t[p].dx; t[y].dx %= PP;
		t[x].d = (ll)t[x].d * t[p].dx % PP;
		t[y].d = (ll)t[y].d * t[p].dx % PP;
		t[p].dx = 1;
	}
	
	if(t[p].dd){
		t[x].dd += t[p].dd; t[y].dd += t[p].dd;
		t[x].d += (ll)t[p].dd * (t[x].r - t[x].l + 1) % PP;
		t[y].d += (ll)t[p].dd * (t[y].r - t[y].l + 1) % PP;
		t[p].dd = 0;
	}
}

void change1(int p, int l, int r, int d){ // x
	if(t[p].l >= l && t[p].r <= r){
		t[p].d = (ll)t[p].d * d % PP;
		t[p].dx = (ll)t[p].dx * d % PP;
		t[p].dd = (ll)t[p].dd * d % PP;
		return ;
	}
	
	don(p);
	int mid = t[p].l + t[p].r >> 1, x = p << 1, y = p << 1 | 1;
	
	if(r > mid) change1(y, l, r, d);
	if(l <= mid) change1(x, l, r, d);
	t[p].d = t[x].d + t[y].d; t[p].d %= PP;
}

void change2(int p, int l, int r, int d){ // +
	if(t[p].l >= l && t[p].r <= r){
		t[p].dd += d;
		t[p].d += (ll)(t[p].r - t[p].l + 1) * d % PP;
		t[p].d %= PP;
		return ;
	}
	
	don(p);
	int mid = t[p].l + t[p].r >> 1, x = p << 1, y = p << 1 | 1;
	
	if(r > mid) change2(y, l, r, d);
	if(l <= mid) change2(x, l, r, d);
	t[p].d = t[x].d + t[y].d; t[p].d %= PP;
}

int ask(int p, int l, int r){
	ll ans = 0;
	if(t[p].l >= l && t[p].r <= r) return t[p].d % PP;
	
	don(p);
	int mid = t[p].l + t[p].r >> 1;
	int x = p << 1, y = p << 1 | 1;
	
	if(l <= mid) ans += ask(x, l, r);
	if(r > mid) ans += ask(y, l, r);
	return ans % PP; 
}

void work1(){// 乘法 
	int x, y, d;
	scanf("%d%d%d",&x,&y,&d);
	change1(1, x, y, d);
}

void work2(){ // 加法 
	int x, y, d;
	scanf("%d%d%d",&x,&y,&d);
	change2(1, x, y, d);
}

void work3(){
	int x, y;
	scanf("%d%d",&x,&y);
	printf("%d\n",ask(1, x, y) % PP);
}

int main(){
	scanf("%d%d%d",&n,&m,&PP);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	makke(1, 1, n);
//	for(int i=0;i<min(3*n,N);i++) t[i].dx = 1;
	
	int k;
	while(m -- ){
		scanf("%d",&k);
		if(k == 3) work3();
		if(k == 2) work2();
		if(k == 1) work1();
	} return 0;
}
2024/11/7 01:35
加载中...