zoukankan      html  css  js  c++  java
  • loj6145. 「2017 山东三轮集训 Day7」Easy

    题面

    题解:由于区间内每个点和(x)的lca都不尽相同,我们很难用(dep_x+dep_y-2 imes dep_{lca})来进行求解。于是考虑点分治,把询问离线下来,挂在点(x)上。

    发现问题变得很简单:我们只需要扫一遍分治中心的所有儿子,先在线段树上查一下区间离它最远的点的距离,然后再把自己加进线段树里就行了,注意正反要各做一遍。由于每个点只会涉及到log次线段树的单点修改、区间查询,时间复杂度就是(O(nlog^2n))

    如果本题强制在线,那么只需要把所有分治中心的线段树(或者平衡树)都建出来,然后在点分树上跳father,注意查的时候要减去它所在子树在线段树上的贡献就行了,这个东西对于做过动态点分治的大神们应该不陌生。

    时间复杂度:(O(nlog^2n))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define F(x,y,z) for(re x=y;x<=z;x++)
    #define FOR(x,y,z) for(re x=y;x>=z;x--)
    typedef long long ll;
    #define I inline void
    #define IN inline int
    #define C(x,y) memset(x,y,sizeof(x))
    #define STS system("pause")
    template<class D>I read(D &res){
    	res=0;register D g=1;register char ch=getchar();
    	while(!isdigit(ch)){
    		if(ch=='-')g=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch)){
    		res=(res<<3)+(res<<1)+(ch^48);
    		ch=getchar();
    	}
    	res*=g;
    }
    const int INF=1e9+7;
    struct E{
    	int to,nt,w;
    }e[202000];
    struct P{
    	int x,y,id;
    	P(int _x=0,int _y=0,int _id=0){x=_x;y=_y;id=_id;}
    };
    #define T e[k].to
    int n,m,rot,head[101000],tot,vis[101000],siz[101000],mx[101000],N,maxi,root,ans[101000];
    vector<int>G[101000],tmp;
    vector<P>t[101000];
    struct Segtree{
    	int tr[404000],laz[404000];
    	#define all 1,1,n
    	#define lt k<<1,l,mid
    	#define rt k<<1|1,mid+1,r
    	I add(int k){tr[k]=INF;laz[k]=1;}
    	I push_down(int k){
    		add(k<<1),add(k<<1|1);laz[k]=0;
    	}
    	I modi(int k,int l,int r,int x,int w){
    		if(l==r)return tr[k]=w,void();
    		if(laz[k])push_down(k);
    		re mid=(l+r)>>1;
    		if(x<=mid)modi(lt,x,w);
    		else modi(rt,x,w);
    		tr[k]=min(tr[k<<1],tr[k<<1|1]);
    	}
    	IN ques(int k,int l,int r,int x,int y){
    		if(x>r||y<l)return INF;
    		if(x<=l&&r<=y)return tr[k];
    		if(laz[k])push_down(k);
    		re mid=(l+r)>>1;
    		return min(ques(lt,x,y),ques(rt,x,y));
    	}
    }S;
    I add(int x,int y,int w){
    	e[++tot].to=y;e[tot].nt=head[x];head[x]=tot;e[tot].w=w;
    }
    I findroot(int x,int fa){
    	siz[x]=1;mx[x]=0;
    	for(re k=head[x];k!=-1;k=e[k].nt){
    		if(T==fa||vis[T])continue;
    		findroot(T,x);mx[x]=max(mx[x],siz[T]);
    		siz[x]+=siz[T];
    	}
    	mx[x]=max(mx[x],N-siz[x]);
    	if(mx[x]<maxi)maxi=mx[x],root=x;
    }
    I D_1(int x,int fa){
    	siz[x]=1;
    	for(re k=head[x];k!=-1;k=e[k].nt){
    		if(T==fa||vis[T])continue;
    		D_1(T,x);siz[x]+=siz[T];
    	}
    }
    I divided(int x,int fa){
    	if(fa)G[fa].emplace_back(x);
    	D_1(x,0);vis[x]=1;
    	for(re k=head[x];k!=-1;k=e[k].nt){
    		if(T==fa||vis[T])continue;
    		N=siz[T];maxi=INF;
    		findroot(T,x);divided(root,x);
    	}
    }
    I D_2(int x,int fa,int dist){
    	for(auto d:t[x])ans[d.id]=min(ans[d.id],S.ques(all,d.x,d.y)+dist);
    	for(re k=head[x];k!=-1;k=e[k].nt){
    		if(T==fa||vis[T])continue;
    		D_2(T,x,dist+e[k].w);
    	}
    }
    I D_3(int x,int fa,int dist){
    	S.modi(all,x,dist);
    	for(re k=head[x];k!=-1;k=e[k].nt){
    		if(T==fa||vis[T])continue;
    		D_3(T,x,dist+e[k].w);
    	}
    }
    I solve(int x){
    	S.add(1);S.modi(all,x,0);tmp.clear();
    	for(re k=head[x];k!=-1;k=e[k].nt){
    		if(vis[T])continue;
    		tmp.emplace_back(k);
    		D_2(T,x,e[k].w);D_3(T,x,e[k].w);
    	}
    	reverse(tmp.begin(),tmp.end());
    	S.add(1);S.modi(all,x,0);
    	for(auto k:tmp)D_2(T,x,e[k].w),D_3(T,x,e[k].w);
    	for(auto d:t[x])ans[d.id]=min(ans[d.id],S.ques(all,d.x,d.y));
    	vis[x]=1;
    	for(auto d:G[x])solve(d);
    }
    int main(){
    	read(n);C(head,-1);tot=-1;
    	re X,Y,W;
    	F(i,1,n-1){
    		read(X);read(Y);read(W);
    		add(X,Y,W);add(Y,X,W);
    	}
    	N=n;maxi=INF;findroot(1,0);rot=root;divided(root,0);
    	read(m);
    	F(i,1,m){
    		read(X);read(Y);read(W);
    		t[W].emplace_back(P(X,Y,i));ans[i]=INF;
    	}
    	C(vis,0);solve(rot);
    	F(i,1,m)printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    VS2010 VC Project的default Include设置
    Linux 下的编辑/编译器
    用命令实现Win7远程桌面关机和重启
    怎样快速刪除Word中超链接?
    chrome浏览器世界之窗浏览器的收藏夹在哪?
    代码量查找工具[最好用的]
    C项目实践--网络协议和套接字编程
    memmove 和 memcopy
    bzoj2456: mode
    bzoj1205: [HNOI2005]星际贸易
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/13347953.html
Copyright © 2011-2022 走看看