• HDU 3078 LCA转RMQ


    题意:

    n个点 m个询问

    下面n个数字表示点权值

    n-1行给定一棵树

    m个询问 k u v

    k为0时把u点权值改为v

    或者问 u-v的路径上 第k大的数

    思路:

    LCA转RMQ求出 LCA(u,v) ;

    登山坡式找到路径上所有点并记录其权值

    排序输出k大的数

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string>
    #include<queue>
    #include<string.h>
    #include<map>
    #include<set>
    #include<stack>
    #include<vector>
    #include<math.h>
    #define N 80010
    using namespace std;
    inline int Max(int a,int b){return a>b?a:b;}
    
    struct node{
    	int from, to, nex;
    }edge[N<<1];
    int head[N], edgenum;
    void addedge(int u, int v){
    	node E = {u, v, head[u]};
    	edge[ edgenum ] = E;
    	head[u] = edgenum ++;
    }
    int val[N], Stack[N];
    
    int time;
    int deep[N<<1], index[N<<1], first[N], pre[N];
    void DFS(int u, int dep){
    	deep[time] = u;
    	index[time] =u;
    	time++;
    	for(int i = head[u]; i !=-1; i = edge[i].nex)
    	{
    		int v = edge[i].to;
    		if(first[v] == 0)
    		{
    			first[v] = time;
    			pre[v] = u;
    			DFS(v, dep+1);
    			deep[time] = u;
    			index[time]= u;
    			time++;
    		}
    	}
    }
    int dp[N<<1][25];
    void RMQ_init(int n){
    	for(int i = 1; i <= n; i++)
    		dp[i][0] = i;
    	for(int j = 1; (1<<j)<=n;j++)
    	{
    		int k = 1<<(j-1);
    		for(int i = 1; i+k<n; i++)
    		{
    			if(deep[ dp[i][j-1] ] <= deep[ dp[i+k][j-1] ])
    				dp[i][j] = dp[i][j-1];
    			else 
    				dp[i][j] = dp[i+k][j-1];
    		}
    	}
    }
    int RMQ(int a,int b){
    	int dis = Max(a-b,b-a) +1;
    	int k = log(double(dis))/ log(2.0);
    	if(deep[dp[a][k]]<= deep[dp[b - (1<<k) +1][k]])
    		return dp[a][k];
    	else
    	return dp[b-(1<<k)+1][k];
    }
    int LCA(int u, int v){
    	int fu = first[u], fv = first[v];
    	return fu<=fv? index[ RMQ(fu,fv)] : index[ RMQ(fv,fu)];
    }
    
    int main()
    {
    	int n, m, i, j, k, que, u, v;
    	int root = 1;
    	while(~scanf("%d%d",&n,&que))
    	{
    		memset(head, -1, sizeof(head)); edgenum = 0;
    		memset(first, 0, sizeof(first));
    
    		for(i=1;i<=n;i++)scanf("%d",&val[i]);
    		for(i=1;i<n;i++)
    		{
    			scanf("%d %d",&u,&v);
    			addedge(u, v);	addedge(v, u);
    		}
    		first[root] = 1;
    		time = 1;
    		DFS(root, 0);
    		RMQ_init(time-1);
    		while(que--){
    			scanf("%d %d %d",&k,&u,&v);
    			if(k==0)
    			{val[u] = v; continue;}
    			if(u==v){
    				if(k==1)printf("%d
    ",val[u]);
    				else printf("invalid request!
    ");continue;
    			}
    			int c = LCA(u, v);
    			int top = 0;
    			Stack[top++] = val[c];
    			while(u!=c)
    			{
    				Stack[top++] = val[u];
    				u = pre[u];
    			}
    			while(v!=c)
    			{
    				Stack[top++] = val[v];
    				v = pre[v];
    			}
    			if(top<k)
    			{printf("invalid request!
    ");continue;}
    			sort(Stack, Stack+top);
    			printf("%d
    ",Stack[top - k]);
    		}
    	}
    	return 0;
    }


     

    8 99
    5 2 3 4 5 6 7 8
    1 3
    1 2
    3 4 
    3 5 
    5 6
    5 7
    7 8
    1 2 8
    2 2 8
    3 2 8
    4 2 8
    5 2 8
    6 2 8
    7 2 8
    1 4 8
    4 2 3
    5 3 8
    2 3 8
    0 3 8
    2 3 8
    3 3 8
    2 4 5
    1 4 1
    2 4 1
    3 4 1
    
    ans:
    8
    7
    5
    5
    3
    2
    in...
    8
    in...
    in...
    7
    8
    7
    5
    8
    5
    4
    
    1 1
    5
    1 1 1
    
    ans:
    5
    
    
    
    2 2
    2 1
    1 2
    2 2 1
    1 1 2
    
    ans:
    1
    2


     

  • 相关阅读:
    搞懂 Python 中多继承与Mixin设计模式
    Python 中的新式类和经典类的区别?
    值得收藏!15个 Pythonic 的代码示例
    windows启动nacos1.3.2
    Linux完成MySQL安装,本地连接时出现1064错误
    vagrant安装的坑
    AvaloniaUI TextBox 不能显示中文的问题解决
    [笔记] zookeeper 本地测试部署
    docker: Error response from daemon: Ports are not available
    smartsql 入门使用踩坑笔记
  • 原文地址:https://www.cnblogs.com/riskyer/p/3424061.html
Copyright © 2020-2023  润新知