zoukankan      html  css  js  c++  java
  • LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树

    这个就比较简单了~

    Code: 

    #include <cstdio> 
    #include <algorithm>  
    #define N 100004 
    #define inf 1000000000   
    #define setIO(s) freopen(s".in","r",stdin)  //    , freopen(s".out","w",stdout)          
    using namespace std;  
    int n,edges; 
    int hd[N],to[N<<1],nex[N<<1],val[N<<1]; 
    void add(int u,int v,int c)
    {
    	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; 
    } 
    namespace tree
    { 
    	int size[N],son[N],dep[N],dis[N],fa[N],top[N];
    	void dfs1(int u,int ff)
    	{ 
    		size[u]=1,fa[u]=ff; 
    		for(int i=hd[u];i;i=nex[i]) 
    			if(to[i]!=ff)
    			{
    				dis[to[i]]=dis[u]+val[i],dep[to[i]]=dep[u]+1; 
    				dfs1(to[i],u),size[u]+=size[to[i]]; 
    				if(size[to[i]]>size[son[u]]) son[u]=to[i];           
    			}
    	} 
    	void dfs2(int u,int tp)
    	{
    		top[u]=tp; 
    		if(son[u]) dfs2(son[u],tp); 
    		for(int i=hd[u];i;i=nex[i]) 
    			if(to[i]!=fa[u]&&to[i]!=son[u]) 
    				dfs2(to[i],to[i]); 
    	} 
    	int LCA(int x,int y)
    	{
    		while(top[x]!=top[y]) 
    			dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]; 
    		return dep[x]<dep[y]?x:y; 
    	}
    	int Dis(int x,int y)
    	{
    		return dis[x]+dis[y]-(dis[LCA(x,y)]<<1); 
    	} 
    }; 
    namespace seg 
    { 
    	int tot;                         
    	#define lson t[x].ls 
    	#define rson t[x].rs
    	struct Node 
    	{
    		int ls,rs,min; 
    	}t[N*100];  
    	int newnode() 
    	{
    		t[++tot].min=inf;           
    		return tot;    
    	}    
    	void pushup(int x) 
    	{ 
    		t[x].min=inf; 
    		if(lson) t[x].min=min(t[x].min,t[lson].min); 
    		if(rson) t[x].min=min(t[x].min,t[rson].min);    
    	}
    	void update(int &x,int l,int r,int p,int v) 
    	{
    		if(!x) x=newnode();    
    		if(l==r) 
    		{ 
    			t[x].min=min(t[x].min,v);      
    			return; 
    		} 
    		int mid=(l+r)>>1; 
    		if(p<=mid) update(lson,l,mid,p,v); 
    		else update(rson,mid+1,r,p,v); 
    		pushup(x); 
    	}   
    	int query(int x,int l,int r,int L,int R) 
    	{
    		if(!x) return inf; 
    		if(l>=L&&r<=R) return t[x].min;     
    		int mid=(l+r)>>1,re=inf; 
    		if(L<=mid) re=min(re,query(lson,l,mid,L,R)); 
    		if(R>mid)  re=min(re,query(rson,mid+1,r,L,R));      
    		return re;    
    	}
    	#undef lson 
    	#undef rson  
    }; 
    int root,sn;
    int size[N],Fa[N],mx[N],vis[N],rt[N]; 
    void getroot(int u,int ff)
    { 
    	size[u]=1,mx[u]=0; 
    	for(int i=hd[u];i;i=nex[i]) 
    		if(to[i]!=ff&&!vis[to[i]]) 
    			getroot(to[i],u),size[u]+=size[to[i]],mx[u]=max(mx[u],size[to[i]]); 
    	mx[u]=max(mx[u],sn-mx[u]);    
    	if(mx[u]<mx[root]) root=u;
    }  
    void dfs(int u,int ff)
    {
    	size[u]=1; 
    	for(int i=hd[u];i;i=nex[i]) 
    		if(to[i]!=ff&&!vis[to[i]]) 
    			dfs(to[i],u),size[u]+=size[to[i]]; 
    }     
    void calc(int u,int ff,int dep,int tp) 
    {    
    	seg::update(rt[tp],1,n,u,dep);           
    	for(int i=hd[u];i;i=nex[i]) 
    		if(to[i]!=ff&&!vis[to[i]]) 
    			calc(to[i],u,dep+val[i],tp);     
    }
    void prepare(int u) 
    { 
    	vis[u]=1,calc(u,0,0,u);        
    	for(int i=hd[u];i;i=nex[i]) 
    		if(!vis[to[i]]) 
    			dfs(to[i],u),root=0,sn=size[to[i]],getroot(to[i],u),Fa[root]=u,prepare(root);     
    }
    int query(int u,int l,int r) 
    {
    	int re=seg::query(rt[u],1,n,l,r),U=u;           
    	for(;Fa[u];u=Fa[u]) 
    		re=min(re, seg::query(rt[Fa[u]],1,n,l,r)+tree::Dis(U,Fa[u]));      
    	return re;       
    }
    int main() 
    { 
    	int i,j,m; 
    	// setIO("input");  
    	scanf("%d",&n); 
    	for(i=1;i<n;++i) 
    	{
    		int a,b,c; 
    		scanf("%d%d%d",&a,&b,&c),add(a,b,c),add(b,a,c); 
    	} 
    	tree::dfs1(1,0),tree::dfs2(1,1);      
    	root=0,mx[root]=sn=n,getroot(1,0),prepare(root);  
    	scanf("%d",&m); 
    	for(i=1;i<=m;++i) 
    	{
    		int l,r,x; 
    		scanf("%d%d%d",&l,&r,&x);      
    		printf("%d
    ",query(x,l,r));     
    	}
    	return 0; 
    }
    

      

  • 相关阅读:
    Simulink模块之Zero-Order Hold和Unit Delay的区别
    芯片电源引脚的去耦电容
    STM32中电源引脚
    Simulink:模块参数初始化
    工作笔记1
    至少清楚知道兼容IE8 ie9 ;持续更新
    FROM_UNIXTIME/CONCAT
    采集文章
    文件上传类(引用)
    php文件相关操作
  • 原文地址:https://www.cnblogs.com/guangheli/p/11456762.html
Copyright © 2011-2022 走看看