线段树30分求助,只过了1,3,4
查看原帖
线段树30分求助,只过了1,3,4
165884
硬核不媚宅楼主2021/10/20 20:34
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define int long long
typedef long long ll;
const int N=1e5+5,INF=0x3f3f3f3f;
int mod;
using namespace std;
int n,a[N];
struct segtree
{
	int l,r,dat,add,mul;
}t[N<<2];
void build(int p,int l,int r)
{
	t[p].l=l;t[p].r=r;t[p].mul=1;
	if(l==r){t[p].dat=a[l];return;}
	int mid=(l+r)/2;
	build(p*2,l,mid);build(p*2+1,mid+1,r);
	t[p].dat=t[p*2].dat+t[p*2+1].dat;
}
void spread(int p)
{
	if(t[p].mul!=1)
	{
		t[p*2].dat=t[p*2].dat*t[p].mul%mod;
		t[p*2+1].dat=t[p*2+1].dat*t[p].mul%mod;
		t[p*2].mul=t[p*2].mul*t[p].mul%mod;
		t[p*2+1].mul=t[p*2+1].mul*t[p].mul%mod;
		t[p].mul=1;
	}
	if(t[p].add)
	{
		t[p*2].dat=(t[p*2].dat+(t[p*2].r-t[p*2].l+1)*t[p].add%mod)%mod;
		t[p*2+1].dat=(t[p*2+1].dat+(t[p*2+1].r-t[p*2+1].l+1)*t[p].add%mod)%mod;
		t[p*2].add=(t[p*2].add*t[p].mul%mod+t[p].add)%mod;t[p*2+1].add=(t[p*2+1].add*t[p].mul+t[p].add);
		t[p].add=0;
	}
}
void change_mul(int p,int l,int r,int k)
{
	if(l<=t[p].l&&t[p].r<=r) {t[p].dat=t[p].dat*k%mod;t[p].mul=t[p].mul*k%mod;t[p].add=t[p].add*k%mod;return ;}
	spread(p);
	int mid=(t[p].l+t[p].r)/2;
	if(l<=mid) change_mul(p*2,l,r,k);
	if(r>mid) change_mul(p*2+1,l,r,k);
	t[p].dat=(t[p*2].dat+t[p*2+1].dat)%mod;
	return ;
}
void change_add(int p,int l,int r,int k)
{
	if(t[p].l>=l&&t[p].r<=r){t[p].dat=(t[p].dat+(t[p].r-t[p].l+1)*k)%mod;t[p].add=(t[p].add+k)%mod;return ;}
	spread(p);
	int mid=(t[p].l+t[p].r)/2;
	if(l<=mid) change_add(p*2,l,r,k);
	if(r>mid) change_add(p*2+1,l,r,k);
	t[p].dat=t[p*2].dat+t[p*2+1].dat;
}
int query(int p,int l,int r)
{
	if(t[p].l>=l&&t[p].r<=r) return t[p].dat;
	spread(p);
	int mid=(t[p].l+t[p].r)/2,sum=0;
	if(l<=mid) sum+=query(p*2,l,r);
	if(r>mid) sum+=query(p*2+1,l,r);
	return sum%mod;
}
signed main()
{
	int Q;
	scanf("%lld%lld%lld",&n,&Q,&mod);
	FOR(i,1,n) scanf("%lld",&a[i]);
	build(1,1,n);
	while(Q--)
	{
		int opt,x,y,k;
		scanf("%lld%lld%lld",&opt,&x,&y);
		if(opt==1) scanf("%lld",&k),change_mul(1,x,y,k);
		else if(opt==2) scanf("%lld",&k),change_add(1,x,y,k);
		else printf("%lld\n",query(1,x,y));
	}
	return 0;
}
2021/10/20 20:34
加载中...