线段树数组应该开几倍?开4倍RE了
查看原帖
线段树数组应该开几倍?开4倍RE了
668765
atom_yan楼主2022/6/7 20:35

结构体那一行如果写maxN<<3或maxN乘6倍就对了,不是说只要开4倍就可以了吗,还是说函数里面哪里超了?

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxN=1e5+5;
inline LL read()
{
	LL sum=0;
	char ch=getchar();
	while(ch>'9'||ch<'0')ch=getchar();
	while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=getchar();
	return sum;
}
struct tree{
	LL val;
	LL add,mul;
}tr[maxN<<4];
int n,m,a[maxN],P;
inline int ls(int p){
	return p<<1;
}
inline int rs(int p){
	return p<<1|1;
}
inline void push_up(int p){
	tr[p].val=(tr[ls(p)].val%P+tr[rs(p)].val%P)%P;
}
inline void build(int p,int l,int r){
	tr[p].mul=1;
	if(l==r){
		tr[p].val=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	push_up(p);
}
void f(int p,int l,int r,LL add,LL mul){
	tr[p].val=(tr[p].val*mul+(r-l+1)*add)%P;
	tr[p].mul=tr[p].mul*mul%P;
	tr[p].add=(tr[p].add*mul+add)%P;
}
void push_down(int p,int l,int r){
	int mid=(l+r)>>1;
	f(ls(p),l,mid,tr[p].add,tr[p].mul);
	f(rs(p),mid+1,r,tr[p].add,tr[p].mul);
	tr[p].add=0;tr[p].mul=1;
}
void update_add(int al,int ar,int nl,int nr,int p,LL k){
	if(al<=nl&&nr<=ar){
		tr[p].val+=k*(nr-nl+1);
		tr[p].val%=P;
		tr[p].add+=k;
		tr[p].add%=P;
		return;
	}
	push_down(p,nl,nr);
	int mid=(nl+nr)>>1;
	if(al<=mid)update_add(al,ar,nl,mid,ls(p),k);
	if(mid<ar)update_add(al,ar,mid+1,nr,rs(p),k);
	push_up(p);
}
void update_mul(int al,int ar,int nl,int nr,int p,LL k){
	if(!tr[p].add)push_down(p,nl,nr);
	if(al<=nl&&nr<=ar){
		tr[p].add*=k;
		tr[p].add%=P;
		tr[p].mul*=k;
		tr[p].mul%=P;
		tr[p].val*=k;
		tr[p].val%=P;
		return;
	}
	push_down(p,nl,nr);
	int mid=(nl+nr)>>1;
	if(al<=mid)update_mul(al,ar,nl,mid,ls(p),k);
	if(mid<ar)update_mul(al,ar,mid+1,nr,rs(p),k);
	push_up(p);
}
inline LL query(int al,int ar,int nl,int nr,int p){
	LL ans=0;
	if(al<=nl&&nr<=ar)return tr[p].val%P;
	push_down(p,nl,nr);
	int mid=(nl+nr)>>1;
	if(al<=mid)ans+=query(al,ar,nl,mid,ls(p));
	ans%=P; 
	if(mid<ar)ans+=query(al,ar,mid+1,nr,rs(p));
	return ans%P;
}
int main(){
	cin>>n>>m>>P;
	for(int i=1;i<=n;i++){
		a[i]=read();
		a[i]%=P;
	}
	build(1,1,n);
	int opt,x,y;
	LL k;
	while(m--){
		opt=read();
		if(opt==1){
			x=read();y=read();k=read();
			update_mul(x,y,1,n,1,k);
		}
		else if(opt==2){
			x=read();y=read();k=read();
			update_add(x,y,1,n,1,k%P);
		}
		else{
			x=read();y=read();
			printf("%lld\n",query(x,y,1,n,1));
		}
	}
	return 0;
}


2022/6/7 20:35
加载中...