线段树模版

先贴一个内存较大的模版吧

int rtl[maxn<<2],rtr[maxn<<2],rtv[maxn<<2],lazy[maxn<<2];
long long rtn[maxn<<2],lazy1[maxn<<2];

void push_down(int p){
	if(lazy[p]>1||lazy1[p]){
		int p1=p<<1|1,p2=(p<<1)+2;
		lazy[p1]=1LL*lazy[p1]*lazy[p]%mod;
		lazy[p2]=1LL*lazy[p2]*lazy[p]%mod;
		rtv[p1]=1LL*rtv[p1]*qmod(lazy[p],rtr[p1]-rtl[p1]+1)%mod;
		rtv[p2]=1LL*rtv[p2]*qmod(lazy[p],rtr[p2]-rtl[p2]+1)%mod;
		lazy[p]=1;
		lazy1[p1]|=lazy1[p];
		lazy1[p2]|=lazy1[p];
		rtn[p1]|=lazy1[p];
		rtn[p2]|=lazy1[p];
		lazy1[p]=0;
	}
}

void push_up(int p){
	int p1=p<<1|1,p2=(p<<1)+2;
	rtv[p]=1LL*rtv[p1]*rtv[p2]%mod;
	rtn[p]=rtn[p1]|rtn[p2];
}

void build(int l,int r,int p){
	rtl[p]=l,rtr[p]=r;
	rtv[p]=1;
	lazy[p]=1;
	rtn[p]=lazy1[p]=0;
	if(l>=r) return ;
	build(l,(l+r)/2,p<<1|1);
	build((l+r)/2+1,r,(p<<1)+2);
}

void update(int l,int r,int v,long long v1,int p){
	// cout<<l<<" "<<r<<endl;
	// cout<<l<<" "<<r<<" "<<rtl[p]<<" "<<rtr[p]<<" "<<endl;
	if(rtl[p]>=l&&r>=rtr[p]){
		lazy[p]=1LL*lazy[p]*v%mod;
		lazy1[p]|=v1;
		rtv[p]=1LL*rtv[p]*qmod(v,(rtr[p]-rtl[p]+1))%mod;
		rtn[p]|=v1;
		return;
	}
	push_down(p);
	int mid=(rtr[p]+rtl[p])/2;
	if(l<=mid){
		update(l,r,v,v1,p<<1|1);
	}
	if(r>mid){
		update(l,r,v,v1,(p<<1)+2);
	}
	push_up(p);
}

int query(int l,int r,int p,long long &v1){
	if(rtl[p]>=l&&rtr[p]<=r){
		v1|=rtn[p];
		return rtv[p];
	}
	push_down(p);
	int mid=(rtr[p]+rtl[p])/2;
	ll ans=1;
	if(l<=mid){
		ans=ans*query(l,r,p<<1|1,v1)%mod;
	}
	if(r>mid){
		ans=ans*query(l,r,(p<<1)+2,v1)%mod;
	}
	return ans;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值