Query on a tree IV SPOJ - QTREE4(动态点分治)

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/88375429

对于每一个子树存一个set,每一个点存一个set,然后你就可以以OJ最短的代码长度换来OJ上最长的运行时间。。。

#include<bits/stdc++.h>
#define maxn 100005
#define lim 19
using namespace std;

char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct))
inline void read(int &res)
{
	char ch;
	bool flag = 0;
	for(;!isdigit(ch=getc());) if(ch=='-') flag = 1;
	for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
	(flag) && (res = -res);
}

int n;
int info[maxn],Prev[maxn<<1],to[maxn<<1],cst[maxn<<1],cnt_e;
inline void Node(int u,int v,int c){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=c; }

int pdis[lim][maxn],pedg[lim][maxn],pdep[maxn],col[maxn],siz[maxn],fa[maxn],had;

multiset<int>s[maxn],g[maxn<<1];
multiset<int>::iterator it,it2;
bool vis[maxn];
int Min,rt;

void DFS(int now,int ff,int tsz)
{
	siz[now] = 1;
	int Max = 0;
	for(int i=info[now];i;i=Prev[i])
		if(to[i]!=ff && !vis[to[i]])
		{
			DFS(to[i],now,tsz);
			Max = max(Max , siz[to[i]]);
			siz[now] += siz[to[i]];
		}
	Max = max(Max , tsz - siz[now]);
	if(Max < Min)
		rt = now , Min = Max;
}

int Findrt(int now,int tsz,int pfa)
{
	rt = -1 , Min = 0x3f3f3f3f;
	DFS(now,0,tsz);
	fa[rt] = pfa;
	return rt;
}

void ser(int now,int ff,int pfa,int dist,int pdp)
{
	g[pfa].insert(dist);siz[now]=1;
	pdis[pdp][now] = dist , pedg[pdp][now] = pfa;
	for(int i=info[now];i;i=Prev[i])
		if(to[i]!=ff && !vis[to[i]])
			ser(to[i],now,pfa,dist+cst[i],pdp),
			siz[now] += siz[to[i]];
}

void Solve(int now,int dp)
{
	pdep[now] = dp;
	vis[now] = 1;
	for(int i=info[now];i;i=Prev[i])
		if(!vis[to[i]])
		{
			ser(to[i],now,i,cst[i],dp);
			s[now].insert(*g[i].rbegin());
		}
	pedg[pdep[now]][now] = 0;
	s[now].insert(0);
	if(s[now].size() >= 2)
	{
		it=s[now].end(),it--,it2=it,it--;
		s[0].insert((*it)+(*it2));
	}
	for(int i=info[now];i;i=Prev[i])
		if(!vis[to[i]])
			Solve(Findrt(to[i],siz[to[i]],now),dp+1);
}

void Modify(int now,int tp)
{
	for(int x=now,i=pdep[now];x;x=fa[x],i--)
	{
		if(s[x].size() >= 2)
		{
			it=s[x].end(),it--,it2=it,it--;
			s[0].erase(s[0].find((*it)+(*it2)));
		}
		int p = pedg[i][now];
		if(!p)
		{
			if(tp) s[x].erase(s[x].find(0));
			else s[x].insert(0);
		}
		else
		{
			if(!g[p].empty())
			{
				s[x].erase(s[x].find(*(g[p].rbegin())));
				if(tp) g[p].erase(g[p].find(pdis[i][now]));
				else g[p].insert(pdis[i][now]);
				if(!g[p].empty()) 
					s[x].insert(*g[p].rbegin());
			}
			else
			{
				if(tp) puts("ERROR");
				else g[p].insert(pdis[i][now]);
				s[x].insert(*g[p].rbegin());
			}
		}
		
		if(s[x].size() >= 2)
		{
			it=s[x].end(),it--,it2=it,it--;
			s[0].insert((*it)+(*it2));
		}
	}
}

int main()
{
	read(n);
	for(int i=1;i<n;i++)
	{
		int u,v,c;
		read(u),read(v),read(c);
		Node(u,v,c),Node(v,u,c);
	}
	Solve(Findrt(1,n,0),0);
	
	int m;read(m);had = n;
	char ch;
	for(;m--;)
	{
		while(!isalpha(ch = getc()));
		if(ch == 'A') 
		{
			if(!s[0].size() && !had) puts("They have disappeared.");
			else 
			{
				if(s[0].empty()) printf("%d\n",0);
				else printf("%d\n",max(*s[0].rbegin(),0));
			}
		}
		else 
		{
			int x;
			scanf("%d",&x);
			col[x] ^= 1;
			if(col[x]) had --;
			else had ++;
			Modify(x,col[x]);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/88375429
今日推荐