线段树/树状数组维护二维偏序的trick

在我们要维护形如\(x_i>x_j\land y_i>y_j\)(或\(x_i\ge x_j\land y_i\ge y_j\))的条件时,可以将所有\((x_i,y_i)\)以x为第一关键字,y为第二关键字进行排序。那么在顺序处理时,\(x_i>x_j\)已经满足,只需满足\(y_i>y_j\),则可用线段树或树状数组维护。

例题:「POI2005」AUT-The Bus

#include <bits/stdc++.h> 
using namespace std;
struct segetree {
	int l,r,tmp1,tmp2;
	long long tmp3;
	struct segenode {
		segenode *ls,*rs;
		long long v;
		segenode() {ls=rs=NULL,v=0;}
	} Root;
	void edi(segenode *k,const int l,const int r) {
		if (l==r) return void(k->v=tmp3);
		if (tmp1<=(l+r)/2)
			edi((k->ls?k->ls:(k->ls=new segenode)),l,(l+r)/2);
		else edi((k->rs?k->rs:(k->rs=new segenode)),(l+r)/2+1,r);
		k->v=max((k->ls?k->ls->v:0),(k->rs?k->rs->v:0));
	}
	long long gs(segenode *k,const int l,const int r) {
		if (tmp1>r||tmp2<l) return 0;
		if (tmp1<=l&&r<=tmp2) return k->v;
		return max((k->ls?gs(k->ls,l,(l+r)/2):0),
		(k->rs?gs(k->rs,(l+r)/2+1,r):0));
	}
	segetree(const int l=0,const int r=0):l(l),r(r) {}
	inline void edi(const int p,const long long v) {
		tmp1=p,tmp3=v; edi(&Root,l,r);
	}
	inline long long gs(const int ql,const int qr) {
		tmp1=ql,tmp2=qr; return gs(&Root,l,r);
	}
} s(1,1e9);
int n,m,k;
long long ans;
pair<int,pair<int,int> > p[100050];

int main() {
	scanf("%d%d%d",&n,&m,&k);
	for (int i=0; i<k; ++i) scanf("%d%d%d",&p[i].first,
	&p[i].second.first,&p[i].second.second);
	sort(p,p+k);
	for (int i=0; i<k; ++i) {
		long long res=s.gs(1,p[i].second.first)+p[i].second.second;
		s.edi(p[i].second.first,res); ans=max(ans,res);
	}
	cout<<ans;
}
上一篇:iOS进阶_Socket(Socket简介&代码演练)


下一篇:kaggle入门之混迹kaggle论坛