求助,关于数据范围!
查看原帖
求助,关于数据范围!
181037
ysmlwudia楼主2021/3/14 16:52

已AC 但我线段树空间明明开了四倍 为什么N设置成100005过不了 要设置成400000才可以?

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<string.h>
#include<queue>
#define ll long long
#define debug cout<<"How badly it works!"<<endl;
using namespace std;
const int N=400005;
ll n,m,p;
struct node{
	ll x,y,sum,lza,lzm;
}f[N<<2];
struct tree{
	#define ls (r<<1)
	#define rs ((r<<1)|1) 
	#define mid ((f[r].x+f[r].y)>>1)
	void pushup(int r){
		f[r].sum=f[ls].sum+f[rs].sum;
		return;
	}
	void pushdown(int r){
		f[ls].lza=(f[r].lza+f[ls].lza*f[r].lzm)%p;//孩子的加法lazy标记乘上父亲的乘法lazy标记 
		f[rs].lza=(f[r].lza+f[rs].lza*f[r].lzm)%p;
		
		f[ls].lzm=(f[ls].lzm*f[r].lzm)%p;//孩子的乘法lazy标记直接乘以父亲的乘法lazy标记 
		f[rs].lzm=(f[rs].lzm*f[r].lzm)%p;
		
		f[ls].sum=(f[ls].sum*f[r].lzm+f[r].lza*(f[ls].y-f[ls].x+1))%p;//sum整体乘上乘法lazy标记,再加上自己区间中数的个数乘以加法lazy标记
		f[rs].sum=(f[rs].sum*f[r].lzm+f[r].lza*(f[rs].y-f[rs].x+1))%p;//(分开算的原因是之前加法lazy标记已经乘上父亲lazy标记了) 
	
		f[r].lza=0;//清空lazy标记 
		f[r].lzm=1;
		return;
	}
	void init(int r,int x,int y){
		f[r].lzm=1;
		f[r].x=x,f[r].y=y;
		if(x==y){
			scanf("%lld",&f[r].sum);
			return;
		}
		init(ls,x,mid);
		init(rs,mid+1,y);
		pushup(r);
	}
	void upd_add(int r,int k,int x,int y){
		pushdown(r);//在点值更新之后下传lazy标记,如果下面更新时写的是k,则位置无影响 
		if(f[r].x>=x&&f[r].y<=y){
			f[r].sum=(f[r].sum+(f[r].y-f[r].x+1)*k)%p;//注意这里的顺序,有影响 
			f[r].lza=(f[r].lza+k)%p;
			return;
		}

		if(x<=mid){
			upd_add(ls,k,x,y);
		}
		if(y>=mid+1){
			upd_add(rs,k,x,y);
		}
		pushup(r);
	}
	void upd_mul(int r,int k,int x,int y){
		pushdown(r);//在点值更新之后下传lazy标记,如果下面写的是k,则无影响 
		if(f[r].x>=x&&f[r].y<=y){
			f[r].sum=(f[r].sum*k)%p;//注意这里的顺序 
			f[r].lzm=(f[r].lzm*k)%p;
			return;
		}
		if(x<=mid){
			upd_mul(ls,k,x,y);
		}
		if(y>=mid+1){
			upd_mul(rs,k,x,y);
		}
		pushup(r);
	}
	ll query(int r,int x,int y){
		pushdown(r);//位置无影响 
		if(f[r].x>=x&&f[r].y<=y){
			return f[r].sum%p;
		}
		ll ans=0;
		if(x<=mid){
			ans+=query(ls,x,y);
			ans%=p;
		}
		if(y>=mid+1){
			ans+=query(rs,x,y);
			ans%=p;
		}
		return ans;
	}
}tr;
int main(){
	scanf("%lld%lld%lld",&n,&m,&p);
	tr.init(1,1,n);
	for(int i=1;i<=m;i++){
		int op,x,y,k;
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&x,&y,&k);
			tr.upd_mul(1,k,x,y);
		}
		if(op==2){
			scanf("%d%d%d",&x,&y,&k);
			tr.upd_add(1,k,x,y);
		}
		if(op==3){
			scanf("%d%d",&x,&y);
			ll ans=tr.query(1,x,y);
			printf("%lld\n",ans%p);
		}
	}
	return 0;
}

2021/3/14 16:52
加载中...