求助,找了很长时间了 ,没发现哪里有错误,求大佬指错
查看原帖
求助,找了很长时间了 ,没发现哪里有错误,求大佬指错
230804
Durancer楼主2020/10/5 15:05
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
const int maxn=100010;
int a[maxn];
struct node{
	int l,r;
	long long num,add,mu;//维护的值,懒标记 
}tree[4*maxn];
int mod;
void build(int ind,int l,int r)//建树顺便赋值 
{
	tree[ind].l=l;
	tree[ind].r=r;
	tree[ind].mu=1;//初始化,不然会无效 
	if(l==r)
	{
		tree[ind].num=a[l]%mod;//找到最后了,赋值 
		return;
	}
	int mid=(l+r)/2;
	build(ind*2,l,mid);
	build(ind*2+1,mid+1,r);
	tree[ind].num=(tree[ind*2].num+tree[ind*2+1].num)%mod;//把其他的都赋值; 
}
void spread(int ind)
{
	//如果此时有懒惰标记	先乘后加 
		tree[ind*2].num=(long long)(tree[ind].mu*tree[ind*2].num+((tree[ind*2].r-tree[ind*2].l+1)*tree[ind].add)%mod)%mod;
		tree[ind*2+1].num=(long long)(tree[ind].mu*tree[ind*2+1].num+((tree[ind*2+1].r-tree[ind*2+1].l+1)*tree[ind].add)%mod)%mod;
		
		tree[ind*2].mu=(long long)(tree[ind*2].mu*tree[ind].mu)%mod;
		tree[ind*2+1].mu=(long long)(tree[ind*2+1].mu*tree[ind].mu)%mod;//把乘法懒标记相乘 
		
		tree[ind*2].add=(long long)(tree[ind*2].add*tree[ind].mu+tree[ind].add)%mod;
		tree[ind*2+1].add==(long long)(tree[ind*2+1].add*tree[ind].mu+tree[ind].add)%mod;
		
		tree[ind].add=0;//懒惰标记传到下面去了;清零 
		tree[ind].mu=1; 
}
void mu(long long ind,long long l,long long r,long long k)
{//区间修改乘 
	if(l<=tree[ind].l&&r>=tree[ind].r)//如果全部包含 
	{
		tree[ind].mu=(tree[ind].mu*k)%mod;//乘号懒标记更新 
		tree[ind].num=(tree[ind].num*k)%mod;//里面存的数更新 
		tree[ind].add=(tree[ind].add*k)%mod;//加号标记更新 
		return; 
	} 
	spread(ind);//所有标记向下传播
	tree[ind].num=tree[ind*2].num+tree[ind*2+1].num;
	if(l<=tree[ind*2].r) mu(ind*2,l,r,k);
	if(r>=tree[ind*2+1].l) mu(ind*2+1,l,r,k);
	tree[ind].num=(tree[ind*2].num+tree[ind*2+1].num)%mod;//进行加法运算 
}
void change(int ind,int l,int r,int k)
{//区间修改加 
	if(l<=tree[ind].l&&r>=tree[ind].r)
	{
		tree[ind].num+=(long long)(tree[ind].num+k*(tree[ind].r-tree[ind].l+1))%mod;//加上这个区间的修整值 
		tree[ind].add=(tree[ind].add+k)%mod;//懒惰标记
		return; 
	}	
	spread(ind);
	tree[ind].num=(tree[ind*2].num+tree[ind*2+1].num)%mod;
	if(tree[ind*2].r>=l) change(ind*2,l,r,k);
	if(tree[ind*2+1].l<=r) change(ind*2+1,l,r,k);
	tree[ind].num=(tree[ind*2].num+tree[ind*2+1].num)%mod;
} 
long long ask(int ind,int l,int r)//区间查询 
{
	if(tree[ind].l>=l&&tree[ind].r<=r) return tree[ind].num;
	spread(ind);//懒惰标记向下传递 
	long long ans=0;
	if(tree[ind*2].r>=l) ans=(ans+ask(ind*2,l,r))%mod;
	if(tree[ind*2+1].l<=r) ans=(ans+ask(ind*2+1,l,r))%mod;
	return ans;
}
int main()
{
	int n,m;
	cin>>n>>m>>mod;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int ques,x,y,k;
		cin>>ques;
		if(ques==1)
		{
			cin>>x>>y>>k;
			mu(1,x,y,k);	
		} 
		if(ques==2)
		{
			cin>>x>>y>>k;
			change(1,x,y,k);
		}
		if(ques==3)
	 	{
	 		cin>>x>>y;
	 		cout<<ask(1,x,y)<<endl;
		}
	}
	return 0; 
}
2020/10/5 15:05
加载中...