[整体二分 || 树套树 || 点分治] BZOJ 4009 [HNOI2015]接水果

整体二分的做法题解很多:http://blog.csdn.net/thy_asdf/article/details/50363672


点分治么 还不会233


树套树么 ORZ


[整体二分 || 树套树 || 点分治] BZOJ 4009 [HNOI2015]接水果_第1张图片


打的整体二分


#include
#include
#include
using namespace std;

inline char nc()
{
	static char buf[100000],*p1=buf,*p2=buf;
	if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
	return *p1++;
}

inline void read(int &x)
{
	char c=nc(),b=1;
	for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
	for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

const int N=100005;

namespace TREE{
	#define V G[p].v
	struct edge{
		int u,v,next;
	};
	edge G[N<<1];
	int head[N],inum;
	inline void add(int u,int v,int p){
		G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
	}
	int clk;
	int size[N],pre[N],last[N],fat[N][21],depth[N];
	inline void dfs(int u,int fa){
		size[u]=1; pre[u]=++clk; depth[u]=depth[fa]+1; fat[u][0]=fa;
		for (int k=1;k<=20;k++) fat[u][k]=fat[fat[u][k-1]][k-1]; 
		for (int p=head[u];p;p=G[p].next)
			if (V!=fa)
				dfs(V,u),size[u]+=size[V];
		last[u]=pre[u]+size[u]-1;
	}
	inline int LCA(int u,int v){  
	    if (depth[u]depth[y])  
            	x=fat[x][k];  
    	return x;  
	}
}

int n,P,Q;
int ans[N];

struct Query{
	int x,y,k;
	int idx;
}que[N],tmp[N];
int qtot;

struct Matrix{
	int x1,x2,y1,y2,key;
	bool operator < (const Matrix &B) const{
		return keyB.r):(x>1;
	tot=0;
	for (int i=l;i<=mid;i++) eve[++tot]=event(mat[i].x1,mat[i].y1,mat[i].y2,1),eve[++tot]=event(mat[i].x2,mat[i].y1,mat[i].y2,-1);
	for (int i=ql;i<=qr;i++) eve[++tot]=event(que[i].x,que[i].y,i,0);
	sort(eve+1,eve+tot+1);
	for (int i=1;i<=tot;i++)
		if (eve[i].r==1)
			BIT::add(eve[i].y1,eve[i].y2,1);
		else if (eve[i].r==-1)
			BIT::add(eve[i].y1,eve[i].y2,-1);
		else if (eve[i].r==0)
			cnt[eve[i].y2]=BIT::query(eve[i].y1);
	int L=ql-1,R=qr+1;
	for (int i=ql;i<=qr;i++)
		if (cnt[i]pre[iv]) swap(iu,iv);
		if ((lca=LCA(iu,iv))==iu)
		{
			w=SecLCA(iv,iu);
			if (pre[w]-1>0)
			{
				mat[++mtot].key=ik;
				mat[mtot].x1=1; mat[mtot].x2=pre[w]-1; mat[mtot].y1=pre[iv]; mat[mtot].y2=last[iv];
			}
			if (last[w]+1<=n)
			{
				mat[++mtot].key=ik;
				mat[mtot].x1=pre[iv]; mat[mtot].x2=last[iv]; mat[mtot].y1=last[w]+1; mat[mtot].y2=n; 
			}
		}
		else
		{
			mat[++mtot].key=ik;
			mat[mtot].x1=pre[iu]; mat[mtot].x2=last[iu]; mat[mtot].y1=pre[iv]; mat[mtot].y2=last[iv];
		}
	}
	sort(mat+1,mat+mtot+1);
	for (int i=1;i<=Q;i++)
	{
		read(iu); read(iv); read(ik);
		if (pre[iu]>pre[iv]) swap(iu,iv);
		que[++qtot].k=ik; que[qtot].x=pre[iu]; que[qtot].y=pre[iv]; que[qtot].idx=i;
	}
	Solve(1,mtot,1,qtot);
	for (int i=1;i<=Q;i++) printf("%d\n",ans[i]);
	return 0;
}

你可能感兴趣的:(点分治,树套树,整体二分)