• SPOJ-QTREE Query on a tree 树链剖分


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - SPOJ-QTREE


    题意概括

      给你一颗树,每两点之间有权值,然后改变一些权值,问一条路径上的最大值。


    题解

      树链剖分裸题。


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    const int N=10005;
    struct Edge{
    	int cnt,y[N*2],z[N*2],nxt[N*2],fst[N];
    	void clear(){
    		cnt=0;
    		memset(fst,0,sizeof fst);
    	}
    	void add(int a,int b,int c){
    		y[++cnt]=b,z[cnt]=c,nxt[cnt]=fst[a],fst[a]=cnt;
    	}
    }g;
    struct edge{
    	int a,b,c;
    }e[N];
    int T,n,pos;
    int fa[N],fadis[N],size[N],depth[N],son[N],top[N],p[N],ap[N];
    int maxv[N*4];
    void Get_Gen_Info(int rt,int pre,int d){
    	depth[rt]=d,fa[rt]=pre,size[rt]=1,son[rt]=-1;
    	for (int i=g.fst[rt];i;i=g.nxt[i])
    		if (g.y[i]!=pre){
    			int s=g.y[i];
    			fadis[s]=g.z[i];
    			Get_Gen_Info(s,rt,d+1);
    			size[rt]+=size[s];
    			if (son[rt]==-1||size[s]>size[son[rt]])
    				son[rt]=s;
    		}
    }
    void Get_Pos(int rt,int tp){
    	top[rt]=tp;
    	if (son[rt]==-1){
    		p[rt]=++pos,ap[pos]=rt;
    		return;
    	}
    	else {
    		p[rt]=++pos,ap[pos]=rt;
    		Get_Pos(son[rt],tp);
    	}
    	for (int i=g.fst[rt];i;i=g.nxt[i]){
    		int s=g.y[i];
    		if (s!=fa[rt]&&s!=son[rt])
    			Get_Pos(s,s);
    	}
    }
    void pushup(int rt){
    	maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);
    }
    void build(int rt,int le,int ri){
    	if (le==ri){
    		maxv[rt]=fadis[ap[le]];
    		return;
    	}
    	int mid=(le+ri)>>1;
    	build(rt<<1,le,mid);
    	build(rt<<1|1,mid+1,ri);
    	pushup(rt);
    }
    void change(int rt,int le,int ri,int pos,int v){
    	if (le==ri){
    		maxv[rt]=v;
    		return;
    	}
    	int mid=(le+ri)>>1;
    	if (pos<=mid)
    		change(rt<<1,le,mid,pos,v);
    	else
    		change(rt<<1|1,mid+1,ri,pos,v);
    	pushup(rt);
    }
    int query(int rt,int le,int ri,int xle,int xri){
    	if (ri<xle||le>xri)
    		return 0;
    	if (xle<=le&&ri<=xri)
    		return maxv[rt];
    	int mid=(le+ri)>>1;
    	return max(query(rt<<1,le,mid,xle,xri),query(rt<<1|1,mid+1,ri,xle,xri));
    }
    int find(int a,int b){
    	int f1=top[a],f2=top[b],ans=0;
    	while (f1!=f2){
    		if (depth[f1]<depth[f2])
    			swap(f1,f2),swap(a,b);
    		ans=max(ans,query(1,1,n,p[f1],p[a]));
    		a=fa[f1],f1=top[a];
    	}
    	if (a==b)
    		return ans;
    	if (depth[a]>depth[b])
    		swap(a,b);
    	return max(ans,query(1,1,n,p[son[a]],p[b]));
    }
    int main(){
    	scanf("%d",&T);
    	while (T--){
    		g.clear();
    		scanf("%d",&n);
    		for (int i=1,a,b,c;i<n;i++){
    			scanf("%d%d%d",&a,&b,&c);
    			e[i].a=a,e[i].b=b,e[i].c=c;
    			g.add(a,b,c);
    			g.add(b,a,c);
    		}
    		pos=0,fadis[1]=0;
    		Get_Gen_Info(1,0,0);
    		Get_Pos(1,1);
    		for (int i=1;i<n;i++)
    			if (depth[e[i].a]>depth[e[i].b])
    				swap(e[i].a,e[i].b);
    		build(1,1,n);
    		char str[10];
    		while (scanf("%s",str)){
    			if (str[0]=='D')
    				break;
    			int a,b;
    			scanf("%d%d",&a,&b);
    			if (str[0]=='Q')
    				printf("%d
    ",find(a,b));
    			else
    				change(1,1,n,p[e[a].b],b);
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    activeMQ
    读写xml
    PLSQL
    oracle语法
    cxf远程调用服务
    FastDFS在linux下的安装和整合nginx实现上传图片和url访问
    dubbo和zookeeper的应用
    solr和Lucene的配置方式和应用
    win10 下安装 MongoDB 数据库支持模块(python)
    nodeJs 对 Mysql 数据库的 curd
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/SPOJ-QTREE.html
Copyright © 2020-2023  润新知