线段树2 70分求助
查看原帖
线段树2 70分求助
80231
pumpkin_porridge楼主2022/11/18 11:56

#2,9,10第一个输出有问题,努力检查了很久都没调好。模p大概也全加了一遍。

提前谢谢大佬帮助。

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long s64;

int n,m;

s64 p;
s64 value[100004];
s64 add[800009];
s64 mult[800009];
s64 init[100004];

void build(int left,int right,int root)
{
   mult[root]=1;
   add[root]=0;
   if(left==right)
   {
   	value[root]=init[left]%p;
   	return;
   }
   int mid=(left+right)>>1;
   build(left,mid,root<<1);
   build(mid+1,right,(root<<1)|1);
   value[root]=(value[root<<1]+value[(root<<1)|1])%p;
}

void pushdown(int root,int left,int right)
{
   if(mult[root]!=1||add[root]!=0)
   {
   	int lchild=root<<1,rchild=(root<<1)|1;
   	int mid=(left+right)>>1;
   	mult[lchild]=(mult[lchild]*mult[root])%p;
   	add[lchild]=((add[lchild]*mult[root])%p+add[root])%p;
   	value[lchild]=((value[lchild]*mult[root])%p+add[root]*(mid-left+1)%p)%p;
   	mult[rchild]=(mult[rchild]*mult[root])%p;
   	add[rchild]=((add[rchild]*mult[root])%p+add[root])%p;
   	value[rchild]=((value[rchild]*mult[root])%p+add[root]*(right-mid)%p)%p;
   	mult[root]=1;add[root]=0;
   }
}

void Mult(int lgoal,int rgoal,s64 k,int l
now,int rnow,int root)
{
   pushdown(root,lnow,rnow);
   if(lgoal<=lnow&&rnow<=rgoal)
   {
   	mult[root]=k;add[root]=(add[root]*k)%p;
   	value[root]=(value[root]*k)%p;
   	return;
   }
   int lc=root<<1,rc=(root<<1)|1,mid=(lnow+rnow)>>1;
   if(lgoal<=mid) Mult(lgoal,rgoal,k,lnow,mid,lc);
   if(mid<rgoal) Mult(lgoal,rgoal,k,mid+1,rnow,rc);
   value[root]=(value[lc]+value[rc])%p;
}

void Add(int lgoal,int rgoal,s64 k,int lnow,int rnow,int root)
{
   pushdown(root,lnow,rnow);
   if(lgoal<=lnow&&rnow<=rgoal)
   {
   	add[root]=(add[root]+k)%p;
   	value[root]=(value[root]+k*(rnow-lnow+1)%p)%p;
   	return;
   }
   int lc=root<<1,rc=(root<<1)|1,mid=(lnow+rnow)>>1;
   if(lgoal<=mid) Add(lgoal,rgoal,k,lnow,mid,lc);
   if(mid<rgoal) Add(lgoal,rgoal,k,mid+1,rnow,rc);
   value[root]=(value[lc]+value[rc])%p;
}

s64 Getsum(int lgoal,int rgoal,int lnow,int rnow,int root)
{
   s64 sum=0;
   pushdown(root,lnow,rnow);
   if(lgoal<=lnow&&rnow<=rgoal)
   {
   	sum=value[root];
   	return sum%p;
   }
   int lc=root<<1,rc=(root<<1)|1,mid=(lnow+rnow)>>1;
   if(lgoal<=mid) sum+=Getsum(lgoal,rgoal,lnow,mid,lc);
   if(mid<rgoal) sum+=Getsum(lgoal,rgoal,mid+1,rnow,rc);
   return sum%p;
}

int main()
{
   cin>>n>>m>>p;
   for(int i=1;i<=n;i++) cin>>init[i];
   build(1,n,1);;
   int op,x,y;
   s64 k;
   while(m--)
   {
   	cin>>op;
   	if(op==1)
   	{
   		cin>>x>>y>>k;
   		Mult(x,y,k,1,n,1);
   	}
   	else if(op==2)
   	{
   		cin>>x>>y>>k;
   		Add(x,y,k,1,n,1);
   	}
   	else if(op==3)
   	{
   		cin>>x>>y;
   		cout<<Getsum(x,y,1,n,1)%p<<endl;
   	}
   }
   return 0;
}
2022/11/18 11:56
加载中...