线段树求调(马蜂良好+悬关)
查看原帖
线段树求调(马蜂良好+悬关)
300166
Zikl楼主2023/11/14 22:03
#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int N=1e5+5;
int n,m,a[N];
int tree[N*4],lazy[N*4];
void pushup(int rt){
	tree[rt]=tree[ls(rt)]+tree[rs(rt)];
}
void build(int rt,int l,int r){
	if(l==r) tree[rt]=a[l];
	else{
		int mid=(l+r)>>1;
		build(ls(rt),l,mid);
		build(rs(rt),mid+1,r);
		pushup(rt);
	}
}
void pushdown(int rt,int l,int r){
	if(lazy[rt]){
		int mid=(l+r)>>1;
		lazy[ls(rt)]+=lazy[rt];
		lazy[rs(rt)]+=lazy[rt];
		tree[ls(rt)]+=lazy[rt]*(mid-l+1);
		tree[rs(rt)]+=lazy[rt]*(r-mid);
		lazy[rt]=0;
	}
}
void update(int rt,int l,int r,int x,int y,int k){
	if(l>=x&&r<=y){
		tree[rt]+=k*(l-r+1),lazy[rt]+=k;
		return;
	}
	int mid=(l+r)>>1;
	pushdown(rt,l,r);
	if(x<=mid) update(ls(rt),l,mid,x,y,k);
	if(y>mid)  update(rs(rt),mid+1,r,x,y,k);
	pushup(rt);
}
int query(int rt,int l,int r,int x,int y){
	if(l>=x&&r<=y) return tree[rt];
	int mid=(l+r)>>1,ans=0;
	pushdown(rt,l,r);
	if(x<=mid) ans+=query(ls(rt),l,mid,x,y);
	if(y>mid)  ans+=query(rs(rt),mid+1,r,x,y);
	return ans;
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt=read();
		if(opt==1){
			int x=read(),y=read(),k=read();
			update(1,1,n,x,y,k);
		}
		if(opt==2){
			int x=read(),y=read();
			printf("%lld\n",query(1,1,n,x,y));
		}
	}
	return 0;
}

这是我今天改良马蜂后的线段树

以下是之前的:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}
const int N=100005;
int n,m,a[N];
int tree[N*4],lazy[N*4];
void maintain(int root){
	tree[root]=tree[root<<1]+tree[root<<1|1];
}
void build(int root,int l,int r){
	if(l==r) tree[root]=a[l];
	else{
		int mid=(l+r)/2;
		build(root<<1,l,mid);
		build(root<<1|1,mid+1,r);
		maintain(root);
	}
}
void pushdown(int root,int l,int r){
	if(lazy[root]){
		int mid=(l+r)/2;
		lazy[root<<1]+=lazy[root];
		lazy[root<<1|1]+=lazy[root];
		tree[root<<1]+=lazy[root]*(mid-l+1);
		tree[root<<1|1]+=lazy[root]*(r-mid);
		lazy[root]=0;
	}
}
void update(int root,int l,int r,int x,int y,int k){
	if(l>=x&&r<=y){
		lazy[root]+=k;
		tree[root]+=k*(r-l+1);
	}
	else{
		int mid=(l+r)/2;
		pushdown(root,l,r);
		if(x<=mid) update(root<<1,l,mid,x,y,k);
		if(mid+1<=y) update(root<<1|1,mid+1,r,x,y,k);
		maintain(root);
	}
}
int query(int root,int l,int r,int x,int y){
	if(l>=x&&r<=y) return tree[root];
	int mid=(l+r)/2,ans=0;
	pushdown(root,l,r);
	if(x<=mid) ans+=query(root<<1,l,mid,x,y);
	if(mid+1<=y) ans+=query(root<<1|1,mid+1,r,x,y);
	return ans; 
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt=read();
		if(opt==1){
			int x=read(),y=read(),k=read();
			update(1,1,n,x,y,k);
		}
		if(opt==2){
			int x=read(),y=read();
			printf("%lld\n",query(1,1,n,x,y));
		}
	}
	return 0;
}

后者AC而前者全WA,我用比较器对了114514回,还是没有找出不同,比较器

2023/11/14 22:03
加载中...