线段树 WA 30pts 求调
查看原帖
线段树 WA 30pts 求调
527300
W_C_B_H楼主2024/7/27 09:52

rt,AC 了 1,3,4

代码:

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define SIZE 400005
typedef long long ll;
#define int ll
struct node
{
	int l,r;
	ll val,tag,tag2;
	node(int al=0,int ar=0,ll av=0,ll at=0,ll at2=1)
	{
		l=al,r=ar,val=av,tag=at,tag2=at2;
	}
}seg[SIZE];	// segment tree 线段树 
int n,T,m;
ll a[MAXN];
bool son[SIZE];
ll build(int p,int x,int y)	//建树 
{
	if(x==y)
	{
		seg[p]=node(x,y,a[x]%m,0,1);
		son[p]=0;
		//cout<<"build("<<p<<","<<x<<","<<y<<")="<<a[x]<<"\n";
		return (a[x]%m);
	}
	int mid = x+((y-x)>>1);
	ll ret = ( build(p*2,x,mid)%m + build(p*2+1,mid+1,y)%m )%m;
	seg[p]=node(x,y,ret%m,0,1);
	son[p]=1;
	//cout<<"build("<<p<<","<<x<<","<<y<<")="<<ret<<"\n";
	return ret;
}
void pushdown(int p)	//下传懒标签 
{
	if(son[p])
	{
		seg[p*2].tag2*=seg[p].tag2;
		seg[p*2].tag2%=m;
		seg[p*2].tag*=seg[p].tag2;
		seg[p*2].tag%=m;
		seg[p*2].tag+=seg[p].tag;
		seg[p*2].tag%=m;
		seg[p*2+1].tag2*=seg[p].tag2;
		seg[p*2+1].tag2%=m;
		seg[p*2+1].tag*=seg[p].tag2;
		seg[p*2+1].tag%=m;
		seg[p*2+1].tag+=seg[p].tag;
		seg[p*2+1].tag%=m;
	}
	seg[p].val*=seg[p].tag2;
	seg[p].val%=m;
	seg[p].tag2=1;
	int tmp=(seg[p].r-seg[p].l+1);
	tmp%=m;
	tmp*=seg[p].tag;
	tmp%=m;
	seg[p].val+=tmp;
	seg[p].val%=m;
	seg[p].tag=0;
}
ll sum(int p,int x,int y)	//区间求和 
{
	pushdown(p);
	int sl=seg[p].l, sr=seg[p].r;
	if(sl>y || sr<x)
	{
		return 0;
	}
	if(sl>=x && sr<=y)
	{
		//printf("[%lld,%lld] sum=%lld tag=%lld tag2=%lld\n", seg[p].l, seg[p].r, seg[p].val, seg[p].tag, seg[p].tag2);
		//cout<<"sum("<<p<<","<<x<<","<<y<<")="<<seg[p].val%m<<"\n";
		return (seg[p].val%m);
	}
	int mid=sl+((sr-sl)>>1);
	ll p1=0,p2=0,ret;
	if(son[p])
	{
		p1=sum(p*2,x,y)%m;
		p2=sum(p*2+1,x,y)%m;
	}	
	ret=p1+p2;
	ret%=m;
	//cout<<"p1="<<p1<<"  p2="<<p2<<"\n";
	//cout<<"sum("<<p<<","<<x<<","<<y<<")="<<ret<<"\n";
	return ret;
}
void add(int p,int x,int y,int d)	//区间加 
{
	//cout<<"add("<<p<<","<<x<<","<<y<<","<<d<<")\n";
	int sl=seg[p].l, sr=seg[p].r;
	pushdown(p);
	if(sl>=x && sr<=y)
	{
		seg[p].tag+=d;
		seg[p].tag%=m;
		pushdown(p);
		//cout<<"add: seg[p]: tag="<<seg[p].tag<<"\n";
		return;
	}
	int tmp=(min(y,sr)-max(x,sl)+1);
	tmp%=m;
	tmp*=d;
	tmp%=m;
	seg[p].val+=tmp;
	seg[p].val%=m;
	//cout<<"add: seg[p]: val="<<seg[p].val<<"\n";
	int mid = (sl + sr) >> 1;
	if(son[p])
	{
		if(mid>=x)
		{
			add(p*2,x,y,d);
		}
		if(mid<y)
		{
			add(p*2+1,x,y,d);
		}
	}
}
void mul(int p,int x,int y,int d)	//区间乘 
{
	//cout<<"mul("<<p<<","<<x<<","<<y<<","<<d<<")\n";
	int sl=seg[p].l, sr=seg[p].r;
	pushdown(p);
	if(sl>=x && sr<=y)
	{
		seg[p].tag2*=d;
		seg[p].tag2%=m;
		seg[p].tag*=d;
		seg[p].tag%=m;
		pushdown(p);
		//cout<<"mul: seg[p]: val="<<seg[p].val<<" tag=0 tag2="<<seg[p].tag2<<"\n";
		return;
	}
	//cout<<"mul: seg[p]: l="<<sl<<" r="<<sr<<"\n";
	//cout<<"mul: seg[p].val更新前: sum(1,max(x,sl),min(y,sr))="<<sum(1,max(x,sl),min(y,sr))<<"\n";
	//cout<<"mul: seg[p]: val="<<seg[p].val<<"\n";
	int mid = (sl + sr) >> 1;
	ll p1=0,p2=0;
	if(son[p])
	{
		if(mid>=x)
		{
			mul(p*2,x,y,d);
		}
		if(mid<y)
		{
			mul(p*2+1,x,y,d);
		}
		p1 = seg[p*2].val * seg[p*2].tag2;
		p1%=m;
		p1+=seg[p*2].tag;
		p1%=m;
		p2 = seg[p*2+1].val * seg[p*2+1].tag2;
		p2%=m;
		p2+=seg[p*2+1].tag;
		p2%=m;
	}
	//cout<<"mul("<<p<<","<<x<<","<<y<<","<<d<<")\n";
	//cout<<"p1="<<p1<<"  p2="<<p2<<"\n";
	seg[p].val=(p1+p2)%m;
}
signed main()
{
	scanf("%lld%lld%lld",&n,&T,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
	}
	build(1,1,n);
	while(T--)
	{
		int op,x,y,k;
		scanf("%lld%lld%lld",&op,&x,&y);
		if(op==1)
		{
			scanf("%lld",&k);
			mul(1,x,y,k);
		}
		else if(op==2)
		{
			scanf("%lld",&k);
			add(1,x,y,k);
		}
		else
		{
			printf("%lld\n",sum(1,x,y)%m);
		}
		/*
		for(int i=1;seg[i].l;i++)
		{
			printf("[%lld,%lld] sum=%lld tag=%lld tag2=%lld\n", seg[i].l, seg[i].r, seg[i].val, seg[i].tag, seg[i].tag2);
		}
		//*/
	}
	return 0;
}
2024/7/27 09:52
加载中...