请求撤下线段树标签或减弱数据
  • 板块P4231 三步必杀
  • 楼主TKXZ133
  • 当前回复13
  • 已保存回复13
  • 发布时间2022/11/6 09:14
  • 上次更新2023/10/27 04:06:58
查看原帖
请求撤下线段树标签或减弱数据
767096
TKXZ133楼主2022/11/6 09:14

这题的标签中标有“线段树”,但在使用线段树时,即使使用了动态开点和一堆优化也还是会MLE,所以请求撤下“线段树”标签或将数据削弱5倍左右

#include <bits/stdc++.h>
using namespace std;
const int N=10010000;
typedef long long ll;

int n,m,tot=1;
ll sum[N];
ll maxn,ans;
ll r1,r2;
ll in1,in2,in3,in4;

struct SN{
	int l,r,t;
	int z,y;
};
struct node{
	SN a[N<<1];
	void add_t(int p,ll k){
		a[p].t+=k;
		if(a[p].l==a[p].r)
			sum[a[p].l]=a[p].t;
		return ;
	}
	void push_down(int p){
		if(a[p].t){
			add_t(a[p].z,a[p].t);
			add_t(a[p].y,a[p].t);
			a[p].t=0;
		}
		return ;
	}
	void build(int p,int l,int r){
		a[p].t=0;a[p].l=l;a[p].r=r;
		if(a[p].l==a[p].r)
			return ;
		a[p].z=++tot;a[p].y=++tot;
		int mid=(a[p].l+a[p].r)>>1;
		build(a[p].z,l,mid);
		build(a[p].y,mid+1,r);
		return ;
	}
	void add(int p,int l,int r,ll k){
		if(l<=a[p].l&&a[p].r<=r){
			add_t(p,k);
			return ;
		}
		push_down(p);
		int mid=(a[p].l+a[p].r)>>1;
		if(l<=mid) add(a[p].z,l,r,k);
		if(r>mid) add(a[p].y,l,r,k);
		return ;
	}
	void copy(int p){
		if(a[p].l==a[p].r){
			r1=r2+sum[a[p].l];
			ans=ans xor r1;
			maxn=max(maxn,r1);
			r2=r1;
			return ;
		}
		push_down(p);
		copy(a[p].z);
		copy(a[p].y);
		return ;
	}
}tree;


int main(){
	scanf("%d%d",&n,&m);
	tree.build(1,1,n);
	for(int i=1;i<=m;i++){
		scanf("%lld%lld%lld%lld",&in1,&in2,&in3,&in4);
		ll d=(in4-in3)/(in2-in1);
		if(in1!=in2) tree.add(1,in1+1,in2,d);
		if(in2!=n) tree.add(1,in2+1,in2+1,-in4);
		tree.add(1,in1,in1,in3);
	}
	tree.copy(1);
	cout<<ans<<' '<<maxn;
	return 0;
}

注:线段树的时间复杂度是正确的,只是会MLE

2022/11/6 09:14
加载中...