zjoi2007 捉迷藏(感谢huanghongxun)

直接贴代码,解释都在注释里
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct heap {
    priority_queue h, d;
    void add(int x){ 
		h.push(x);
		return;
	}
    void del(int x){ 
		d.push(x);
		return;
	}
    void exc(int x,int f){
		if(f) add(x);
		else del(x); 
		return;
	}
    void fix(){ 
		while(d.size()&&h.top()==d.top())
			h.pop(),d.pop();
		return;
	}
    void pop(){ 
		fix();
		h.pop();
		return;
	}
    int fir(){ 
		fix(); 
		return h.top(); 
	}
    int sec(){ 
		int a,b;
		a=fir();
		pop();
		b=fir();
		add(a);
		return b;
	}
    int sze(){ 
		return h.size()-d.size();
	}
} s1[100100], s2[100100], ans;
int tot=1,total,root,id,n,a,b,q,onfable;
int nxt[200200],first[100100],goal[200200],size[100100],maxson[100100],ori[100100],r[200200][18],dep[100100],posin[100100],lb[200200];
bool vis[200200],onf[100100];
char order[100];
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();ch>'9'||ch<'0';ch=getchar())	
		if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())
		i=(i<<1)+(i<<3)+(ch^48);
	return i;
}
inline void addedge(int a,int b){
	++tot;
	nxt[tot]=first[a];
	first[a]=tot;
	goal[tot]=b;
	++tot;
	nxt[tot]=first[b];
	first[b]=tot;
	goal[tot]=a;
	return ;
}//邻接表 
void dfsroot(int pos,int fa){
	size[pos]=1,maxson[pos]=0;
	for(int p=first[pos];p;p=nxt[p])
		if(goal[p]!=fa&&!vis[p]){
			dfsroot(goal[p],pos);
			size[pos]+=size[goal[p]];
			if(size[goal[p]]>maxson[pos]) maxson[pos]=size[goal[p]];
		}
	if(total-size[pos]>maxson[pos])	maxson[pos]=total-size[pos];
	if(maxson[pos]=2)
		ans.add(s.fir()+s.sec());
	return ;
}
void delmore(heap &s){
	if(s.sze()>=2)
		ans.del(s.fir()+s.sec());
	return ;
}
void work(int pos){
	s2[pos].add(0);// s1:子树各点到根节点距离,s2:子树各节点s1最大值 
	for(int p=first[pos];p;p=nxt[p])//对每棵子树进行搜索 
		if(!vis[p]){
			vis[p]=vis[p^1]=true;//封锁边防止重复经过 
			heap s;
			dfsorder(goal[p],0,1,s);//先求所有点到根节点距离,塞入临时构建的s中 
			int nxtroot=getroot(goal[p],pos,size[goal[p]]);//求子树中的重心以建一颗重心树 
			ori[nxtroot]=pos;//连接 
			s1[nxtroot]=s;//转移数据 
			s2[pos].add(s1[nxtroot].fir());//只加上重心里s1至大即可 
			work(nxtroot);//递归解决 
		}
	addmore(s2[pos]);//将结果塞入ans中 
	return ;
}
void dfsseq(int pos,int fa){
	r[++id][0]=dep[pos]=dep[fa]+1;//1.确定每个点深度,以解决修改问题2.确定每个点到根节点距离3.建立id序 
	posin[pos]=id;//确定对应节点编号 
	for(int p=first[pos];p;p=nxt[p])
		if(goal[p]!=fa){
			dfsseq(goal[p],pos);
			r[++id][0]=dep[pos];
		}
	return ;
}
void cleanrmq(int s){
	int i,j; 
	for(int i=2;i<=s;++i)
		lb[i]=lb[i>>1]+1;//确定id序节点所在层 
	for(int j=1;j<=lb[s];++j)
		for(int i=1;i<=(s+1-(1<b) swap(a,b);
	int t=lb[b-a+1];//t为相差层数 
	return min(r[a][t],r[b-(1<

你可能感兴趣的:(OI,分治纲)