GDCPC Kera's line segment (二维树状数组)

GDCPC Kera's line segment

Mean

初始给定\(n\)个线段,每个线段有一个权值\(val_i\)\(q\)次操作,有两种操作
1.加入一条坐标在\([l,r]\)且权值为\(val\)的线段。

2.询问区间\([l,r]\)内被完全包含的线段中的权值的最大差值。

强制在线.

Sol

二维树状数组

以左端点为第一维,右端点为第二维,操作2就变成了询问矩阵最大值和最小值.

插入操作就变成了在二维数据结构上单点修改.

用二维线段树也行,用树状数组的话就要把第一维置换一下,因为要维护前缀关系的最大值.

由于置换了第一维的\(x\),那么原本询问的\([l,r]\),在置换后第一维上的表现为第一维询问前缀\([1,3000-l+1]\).

在这段前缀中,第二维大于\(r\)的信息映射回去时,一定不在区间\([l,r]\)内,所以只需要在第二维询问前缀\([1,r]\)即可.

Code

#include<bits/stdc++.h>
using namespace std;
int n,m;
int lmx=3000;
const int N = 3e3+10;
multiset<int>ve[3001];
multiset<int>::iterator it;
#define ls rt<<1
#define rs rt<<1|1
#define mid ((l+r)>>1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define lowbit(x) (x&(-x))
#define rep(i,a,b) for(int i=a;i<=b;++i)
struct node{
	int tr[N][N];
	int tr1[N][N];
	void init(){
	    for(int i=1;i<N;++i){
                for(int j=1;j<N;++j){
                    tr1[i][j]=0x3f3f3f3f;
                    tr[i][j]=0;
                }
            }
	}
	void update(int l,int r,int val){
            l=3001-l;
	    while(l<N){
              int rr=r;
              while(rr<N){
                 tr1[l][rr]=min(tr1[l][rr],val);         
                 tr[l][rr]=max(tr[l][rr],val);
                 rr+=lowbit(rr);
              }
              l+=lowbit(l);
	    }
	}
	
	int get1(int l,int r){
	    int mx=0,mi=0x3f3f3f3f;
            l=3001-l;
	    while(l){
                int rr=r;
                while(rr){
                    mi=min(tr1[l][rr],mi);         
                    mx=max(tr[l][rr],mx);
                    rr-=lowbit(rr);
                }
               l-=lowbit(l);
	    }
	    return max(0,(mx-mi));
	}
	
}tt;
int main(){
	//freopen("in.txt","r",stdin);
	scanf("%d%d",&n,&m);
	int ans=0;
	tt.init();
	rep(i,1,n){
		int l,r,val;
		scanf("%d%d%d",&l,&r,&val);
		tt.update(l,r,val);
	}
	rep(i,1,m){
		int op,l,r,val;
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&l,&r,&val);
			l=(l^ans),r=(r^ans);
			if(l>r)swap(l,r);
			tt.update(l,r,val);
		}
		else{
			scanf("%d%d",&l,&r);
			l=(l^ans),r=(r^ans);
			if(l>r)swap(l,r);
			ans=tt.get1(l,r);
			printf("%d\n",ans);
         
		}
	}
	return 0;
}
posted @ 2021-10-18 11:22  Qquun  阅读(112)  评论(0)    收藏  举报