[ZJOI2019]线段树(线段树,DP)

又是神仙题。

要写博客太长了,先咕着。放个代码先。

为什么 fmul 在 linux 底下还被定义过了……能想象到我一发 CE 的绝望吗 qaq

#include<bits/stdc++.h>
using namespace std;
const int maxn=800080,mod=998244353;
#define ls o<<1
#define rs o<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline int read(){
	int x=0,f=0;char ch=getchar();
	while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
	return f?-x:x;
}
int n,m,f[maxn],g[maxn],sum[maxn],fm[maxn],gm[maxn],pt[maxn];
inline void pushup(int o){
	sum[o]=(sum[ls]+(sum[rs]+f[o])%mod)%mod;
}
inline void setf(int o,int v){
	f[o]=1ll*f[o]*v%mod;
	sum[o]=1ll*sum[o]*v%mod;
	fm[o]=1ll*fm[o]*v%mod;
}
inline void setg(int o,int v){
	g[o]=1ll*g[o]*v%mod;
	gm[o]=1ll*gm[o]*v%mod; 
}
inline void pushdown(int o){
	if(fm[o]!=1){
		setf(ls,fm[o]);
		setf(rs,fm[o]);
		fm[o]=1;
	}
	if(gm[o]!=1){
		setg(ls,gm[o]);
		setg(rs,gm[o]);
		gm[o]=1;
	}
}
void build(int o,int l,int r){
	g[o]=fm[o]=gm[o]=1;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(lson);build(rson);
	pushup(o);
}
void update(int o,int l,int r,int ql,int qr,int id){
	pushdown(o);
	if(r<ql || l>qr){
		f[o]=(f[o]+(pt[id-1]-g[o]+mod)%mod)%mod;
		g[o]=2ll*g[o]%mod;
		setf(ls,2);setf(rs,2);
		setg(ls,2);setg(rs,2);
		pushup(o);
		return;
	}
	if(l>=ql && r<=qr){
		f[o]=(f[o]+pt[id-1])%mod;
		setf(ls,2);setf(rs,2);
		pushup(o);
		return;
	}
	g[o]=(g[o]+pt[id-1])%mod;
	int mid=(l+r)>>1;
	update(lson,ql,qr,id);
	update(rson,ql,qr,id);
	pushup(o);
}
int main(){
	n=read();m=read();
	pt[0]=1;
	FOR(i,1,m) pt[i]=2ll*pt[i-1]%mod;
	build(1,1,n);
	int cnt=0;
	while(m--){
		int op=read();
		if(op==1){
			int l=read(),r=read();
			update(1,1,n,l,r,++cnt);
		}
		else printf("%d
",sum[1]);
	}
}
原文地址:https://www.cnblogs.com/1000Suns/p/11558407.html