记录编号 386057 评测结果 AAAAAAAAAAAAAAAATTTA
题目名称 [HNOI 2010]城市建设 最终得分 85
用户昵称 Gravatarliaoy 是否通过 未通过
代码语言 C++ 运行时间 10.909 s
提交时间 2017-03-23 11:46:26 内存使用 9.27 MiB
显示代码纯文本
#include<cstdio>
#include<vector>
using namespace std;
char ch;
inline void read(int &a){
	for(ch=getchar();ch>'9'||ch<'0';ch=getchar());
	for(a=0;ch<='9'&&ch>='0';ch=getchar())(a*=10)+=ch-'0';
}
int n,m,q;
struct rec{
	int u,v,num,w;
}E[50010];
int L[50010],R[50010];
struct node{
	vector<rec> E;
	int m,l,r;
}Seg[50010<<2];
void Segbuild(const int &p,const int &l,const int &r){
	Seg[p].l=l; Seg[p].r=r; Seg[p].m=(l+r)>>1; if(l==r)return;
	Segbuild(p<<1,l,Seg[p].m); Segbuild(p<<1|1,Seg[p].m+1,r);
}
void put(const int &p,const rec &x,const int &l,const int &r){
	if(Seg[p].l==l&&Seg[p].r==r){
		Seg[p].E.push_back(x);
		return;
	}
	if(r<=Seg[p].m)put(p<<1,x,l,r);
	else
	if(Seg[p].m+1<=l)put(p<<1|1,x,l,r);
	else
	put(p<<1,x,l,Seg[p].m),put(p<<1|1,x,Seg[p].m+1,r);
}
long long sum;
struct LCT{
	struct node{
		int u;
		int s[2],data,maxp;
		bool inv;
		bool operator <(const node &x)const{
			return data<x.data;
		}
	}Btr[70010];
	int Fa[70010];
	int f,gf,v,s;
	inline void newdata(const int &p,const int &w){
		Btr[p].data=w; Btr[p].maxp=p;
	}
	void unite(const int &p){
		Btr[p].maxp=Btr[Btr[Btr[p].s[0]].maxp]<Btr[Btr[Btr[p].s[1]].maxp]?Btr[Btr[p].s[1]].maxp:Btr[Btr[p].s[0]].maxp;
		if(Btr[Btr[p].maxp]<Btr[p])Btr[p].maxp=p;
	}
	inline void flip(const int &p){
		if(Btr[p].inv){
			swap(Btr[p].s[0],Btr[p].s[1]);
			Btr[Btr[p].s[0]].inv^=1; Btr[Btr[p].s[1]].inv^=1; Btr[p].inv^=1;
		}
	}
	void rot(const int &p){
		f=Fa[p]; gf=Fa[f]; v=Btr[f].s[0]!=p;
		s=Btr[p].s[v^1]; Btr[p].s[v^1]=f; Btr[f].s[v]=s; Fa[s]=f; Fa[p]=gf; Fa[f]=p; unite(f); unite(p);
		if(gf){if(Btr[gf].s[0]==f)Btr[gf].s[0]=p;else if(Btr[gf].s[1]==f)Btr[gf].s[1]=p;}
	}
	inline bool Beroot(const int &p){
		return Btr[Fa[p]].s[0]!=p&&Btr[Fa[p]].s[1]!=p;
	}
	int stk[70010]; int stktop;
	void Splay(const int &p){
		for(v=p;!Beroot(v);v=Fa[v])stk[++stktop]=v; stk[++stktop]=v;
		while(stktop)flip(stk[stktop--]);
		for(;!Beroot(Fa[p])&&!Beroot(p);rot(p)){
			if((Btr[Fa[Fa[p]]].s[0]!=Fa[p])^(Btr[Fa[p]].s[0]!=p))rot(p);else rot(Fa[p]);
		}
		if(!Beroot(p))rot(p);
	}
	int t;
	void Access(int p){
		for(t=0;p;t=p,p=Fa[p]){
			Splay(p); Btr[p].s[1]=t; unite(p);
		}
	}
	void Make_root(const int &x){
		Access(x); Splay(x); Btr[x].inv^=1;
	}
	void Link(const int &x,const int &y){
		sum+=Btr[x].data+Btr[y].data;
		Make_root(x); Fa[x]=y;
	}
	/*
	void Cut(const int &x,const int &y){
		sum-=Btr[x].data+Btr[y].data;
		Make_root(x); Access(y); Splay(x);
		Btr[x].s[1]=0; Fa[y]=0; unite(x);
	}
	*/
	void Cut(const int &x,const int &u,const int &v){
		sum-=Btr[x].data<<1;
		Make_root(x);
		Access(u); Splay(x); Btr[x].s[1]=0; Fa[u]=0; unite(x);
		Access(v); Splay(x); Btr[x].s[1]=0; Fa[v]=0; unite(x);
	}
	int Getfa(int x){
		Access(x); Splay(x);
		for(flip(x);Btr[x].s[0];flip(x))x=Btr[x].s[0];
		return x;
	}
	bool Query(int x,const int &y){
		return Getfa(x)==Getfa(y);
		/*
		Make_root(x); Access(y); Splay(x);
		for(flip(x);Btr[x].s[1];flip(x))x=Btr[x].s[1];
//		Splay(x);
		return x==y;
		*/
	}
}T;
int Fa[20010],Size[20010];
struct ope{
	int x,y;/*表示把x的fa变为了y*/
}D[50010];
int Getfa(int u){
	for(;u!=Fa[u];u=Fa[u]); return u;
}
void unite(const int &num,const int &u,const int &v){
	int fu=Getfa(u),fv=Getfa(v); if(fu==fv)return;
	if(Size[fu]>Size[fv])swap(fu,fv); Fa[fu]=fv; Size[fv]+=Size[fu]; D[num].x=fu; D[num].y=fv;
}
inline void cancel(const int &num){
	if(!D[num].x)return;
	Size[D[num].y]-=Size[D[num].x]; Fa[D[num].x]=D[num].x; D[num].x=D[num].y=0;
}
bool Query(const int &u,const int &v){
	return Getfa(u)==Getfa(v);
}
long long Ans[50010];
struct opt{
	int foru;
	/*
	O[i]表示E[i]这条边,切断了foru(LCT中的点)。
	特别的,如果foru为0表示没有切断(但还是插入了这条边),如果foru为-1表示没有操作或者操作失败 
	*/
}O[50010];
void SegDiv(const int &p,const int &l,const int &r){
	int vi,u,v,w,num,maxp;
	for(vi=0;vi<Seg[p].E.size();vi++){
		u=Seg[p].E[vi].u; v=Seg[p].E[vi].v; w=Seg[p].E[vi].w; num=Seg[p].E[vi].num;
		if(!Query(u,v)){
			T.newdata(num+n,w);/*important*/
			T.Link(num+n,u); T.Link(num+n,v); unite(num,u,v);
			O[num].foru=0;
		}else{
			T.Make_root(u); T.Access(v); T.Splay(u);
			maxp=T.Btr[u].maxp;
			if(T.Btr[maxp].data<=w)continue;
			T.newdata(num+n,w);/*important*/
			O[num].foru=maxp;
			T.Cut(maxp,E[maxp-n].u,E[maxp-n].v);T.Link(num+n,u); T.Link(num+n,v);
		}
	}
	if(l!=r){
		SegDiv(p<<1,l,Seg[p].m); SegDiv(p<<1|1,Seg[p].m+1,r);	
	}else{
		Ans[l]=sum>>1;
	}
	for(vi=Seg[p].E.size()-1;vi>=0;vi--){
		num=Seg[p].E[vi].num;
		if(O[num].foru==-1)continue;else{
			T.Cut(num+n,E[num].u,E[num].v); cancel(num);
			if(O[num].foru){
				T.Link(O[num].foru,E[O[num].foru-n].u); T.Link(O[num].foru,E[O[num].foru-n].v);
			}
			O[num].foru=-1;
		}
	}
}
int main(){
	int i,k,w;
	freopen("hnoi2010_city.in","r",stdin); freopen("hnoi2010_city.out","w",stdout);
	read(n); read(m); read(q);
	for(i=1;i<=n;i++)Fa[i]=i,Size[i]=1;
	Segbuild(1,0,q);
	for(i=1;i<=m;i++)read(E[i].u),read(E[i].v),read(E[i].w),E[i].num=i,O[i].foru=-1;
	for(i=1;i<=q;i++){
		read(k); read(w); R[k]=i-1; put(1,E[k],L[k],R[k]); L[k]=i; E[k].w=w;
	}
	for(i=1;i<=m;i++)put(1,E[i],L[i],q);
	SegDiv(1,0,q);
	for(i=1;i<=q;i++)printf("%lld\n",Ans[i]);
}