见鬼了,线段树10分!!!
查看原帖
见鬼了,线段树10分!!!
658786
STUDENT00楼主2022/11/19 09:35

代码如下:

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
#define N 200010
using namespace std;
int n,m,mark[N<<2],mins[N<<2],maxs[N<<2],a[N],q[N],ans;
void push_up(int rt){
	maxs[rt]=max(maxs[rt<<1],maxs[rt<<1|1]);
	mins[rt]=min(mins[rt<<1],mins[rt<<1|1]);
}
void push_down(int rt){
	if(mark[rt]){
		mark[rt<<1]+=mark[rt];
		mark[rt<<1|1]+=mark[rt];
		mins[rt<<1]+=mark[rt];
		mins[rt<<1|1]+=mark[rt];
		mark[rt]=0;
		return;
	}
}
void build(int l,int r,int rt){
	if(l==r){
		scanf("%lld",&maxs[rt]);
		mark[rt]=mins[rt]=0;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,rt<<1);
	build(mid+1,r,rt<<1|1);
	push_up(rt);
}
void update(int l,int r,int rt,int a,int b,int c){
	if(maxs[rt]<=1) return;
	if(a<=l&&b>=r&&(c==2||mins[rt])){
		if(c==2){
			mark[rt]++; 
			mins[rt]++;
		}else{
			mark[rt]--;
			mins[rt]--;
		}
		return;
	}
	if(l==r&&c==1){
		maxs[rt]=sqrt(maxs[rt]);
		return;
	}
	push_down(rt);
	int mid=(l+r)>>1;
	if(a<=mid) update(l,mid,rt<<1,a,b,c);
	if(b>mid) update(mid+1,r,rt<<1|1,a,b,c);
	push_up(rt);
}
int qpow(int a,int b){
	if(b==0) return 1;
	int s=a; 
	while(--b) s=s*s%mod;
	return s;
}
void query(int l,int r,int rt){
	if(l==r){
		a[l]=maxs[rt];
		q[l]=mark[rt];
		return;
	}
	push_down(rt);
	int mid=(l+r)>>1;
	query(l,mid,rt<<1);
	query(mid+1,r,rt<<1|1);
}
signed main(){
	scanf("%lld%lld",&n,&m);
	build(1,n,1);
	while(m--){
		int op,l,r;
		scanf("%lld%lld%lld",&op,&l,&r);
		update(1,n,1,l,r,op);
	}
	query(1,n,1);
	for(int i=1;i<=n;i++) ans=(ans+qpow(a[i],qpow(2,q[i])))%mod;
	printf("%lld",ans);
	return 0;
}
2022/11/19 09:35
加载中...