BZOJ3624: [Apio2008]免费道路 Kruskal+构造
BZOJ3331: [BeiJing2013]压力 图连通性

3526: [Poi2014]Card 线段树

shinbokuow posted @ Sep 05, 2015 06:24:24 PM in BZOJ with tags 线段树 , 1363 阅读

 

题解:

考虑对于每个线段树节点记录如果第一个元素选择比较大的,那么最后一个元素最小是多少;选择比较小的同理。

如果不能选到节点的最后一个元素则值为$\infty$。

信息非常容易维护与合并。

交换操作相当于线段树的单点修改。

这样的话就在$O(mlogn)$之内解决了。

代码:

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
using namespace std;

#define inf 0x3f3f3f3f

inline int getc(){
	static const int L=1<<15;
	static char buf[L],*S=buf,*T=buf;
	if(S==T){
		T=(S=buf)+fread(buf,1,L,stdin);
		if(S==T)
			return EOF;
	}
	return*S++;
}
inline int getint(){
	int c;
	while(!isdigit(c=getc()));
	int x=c-'0';
	while(isdigit(c=getc()))
		x=(x<<1)+(x<<3)+c-'0';
	return x;
}

inline void mini(int&x,int y){
	if(x>y)
		x=y;
}
struct Ans{
	int mx[2],mn[2];
	inline void init(int x,int y){
		if(x>y)
			swap(x,y);
		mn[0]=mn[1]=x;
		mx[0]=mx[1]=y;
	}
	friend Ans operator+(const Ans&l,const Ans&r){
		Ans re;
		re.mn[0]=l.mn[0];
		re.mn[1]=inf;
		if(l.mn[1]<=r.mn[0])
			mini(re.mn[1],r.mn[1]);
		if(l.mn[1]<=r.mx[0])
			mini(re.mn[1],r.mx[1]);
		re.mx[0]=l.mx[0];
		re.mx[1]=inf;
		if(l.mx[1]<=r.mn[0])
			mini(re.mx[1],r.mn[1]);
		if(l.mx[1]<=r.mx[0])
			mini(re.mx[1],r.mx[1]);
		return re;
	}
};

#define N 200010
#define l(x) S[x].l
#define r(x) S[x].r
struct Node{
	int l,r;
	Ans x;
}S[N<<1];

int a[N],b[N],cnt;
inline int build(int tl,int tr){
	int q=++cnt;
	if(tl==tr){
		S[q].x.init(a[tl],b[tl]);
		return q;
	}
	int mid=(tl+tr)>>1;
	l(q)=build(tl,mid);
	r(q)=build(mid+1,tr);
	S[q].x=S[l(q)].x+S[r(q)].x;
	return q;
}

inline void modify(int q,int tl,int tr,int ins,int x,int y){
	if(tl==tr){
		S[q].x.init(x,y);
		return;
	}
	int mid=(tl+tr)>>1;
	if(ins<=mid)
		modify(S[q].l,tl,mid,ins,x,y);
	else
		modify(S[q].r,mid+1,tr,ins,x,y);
	S[q].x=S[l(q)].x+S[r(q)].x;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("tt.in","r",stdin);
#endif
	int n=getint(),i,j;
	for(i=1;i<=n;++i){
		a[i]=getint();
		b[i]=getint();
	}
	build(1,n);
	int m=getint(),c,d,ca,cb,da,db;
	while(m--){
		c=getint();
		d=getint();
		ca=a[c],cb=b[c];
		da=a[d],db=b[d];
		modify(1,1,n,c,a[c]=da,b[c]=db);
		modify(1,1,n,d,a[d]=ca,b[d]=cb);
		if(S[1].x.mn[1]!=inf||S[1].x.mx[1]!=inf)
			puts("TAK");
		else
			puts("NIE");
	}
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter