zoukankan      html  css  js  c++  java
  • [hdu3078]Network(LCA+排序)

    题意:维护树上两点之间的最短路径,其一,将点a的值变为b,其二,求路径上第k大的值。

    解题关键:LCA+sort

    复杂度:$O(qnlog n + nlog n)$ 数据弱不怪我

      1 //#pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<iostream>
      8 #include<vector>
      9 typedef long long ll;
     10 using namespace std;  
     11 const int maxn=81000; 
     12 const int maxm=30;  
     13 int _pow[maxm],m,n;  
     14 int head[maxn],tot;
     15 int ver[maxn*2],depth[maxn*2],first[maxn],rmq[maxn*2][25],id;//5个数组,注意哪个需要乘2 
     16 int pre[maxn],val[maxn];
     17 inline int read(){
     18     char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar());
     19     int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0';
     20     if(k=='-')x=0-x;return x;
     21 }
     22 
     23 struct edge{
     24     int to,nxt;  
     25 }e[maxn*2];//链式前向星建树 
     26 
     27 void init(){
     28     memset(head,-1,sizeof head); 
     29     tot=0;
     30     id=0;
     31 }
     32 
     33 void add_edge(int u,int v){  
     34     e[tot].to=v;
     35     e[tot].nxt=head[u];
     36     head[u]=tot++;
     37 }
     38   
     39 void dfs(int u,int fa,int dep){
     40     ver[++id]=u;//第i个访问到的结点编号 
     41     depth[id]=dep;//第i个访问到的结点深度  
     42     first[u]=id;
     43     for(int i=head[u];i!=-1;i=e[i].nxt){
     44         int v=e[i].to;
     45         if(v==fa) continue;
     46         pre[v]=u;
     47         dfs(v,u,dep+1);
     48         ver[++id]=u;//后序遍历,再次访问父节点 
     49         depth[id]=dep;
     50     }
     51 }
     52 
     53 void rmq_init(int n){
     54     int k=int(log(n)/log(2));
     55     for(int i=1;i<=n;++i)    rmq[i][0]=i;  
     56     for(int j=1;j<=k;++j){  
     57         for(int i=1;i+_pow[j]-1<=n;++i){//因为存的是索引 
     58             int a=rmq[i][j-1],b=rmq[i+_pow[j-1]][j-1];  
     59             rmq[i][j]=depth[a]<depth[b]?a:b;
     60         }
     61     }
     62 }
     63   
     64 int rmq_query(int l,int r){
     65     int k=int(log(r-l+1.0)/log(2.0));  
     66     int a=rmq[l][k],b=rmq[r-_pow[k]+1][k];  
     67     return depth[a]<depth[b]?a:b;
     68 }//返回的依然是索引 
     69   
     70 int LCA(int u,int v){
     71     int x=first[u],y=first[v];  
     72     if(x>y)swap(x,y);  
     73     int res=rmq_query(x,y);  
     74     return ver[res]; 
     75 }
     76 
     77 vector<int>path;
     78 //int path[maxn];
     79 void solve(int k,int a,int b){
     80     //int cnt=0;
     81     path.clear();
     82     int lca=LCA(a,b);
     83     while(b!=lca) path.push_back(val[b]),b=pre[b];
     84     while(a!=lca) path.push_back(val[a]),a=pre[a];
     85     path.push_back(val[lca]);
     86     if(path.size()<k){
     87         printf("invalid request!
    ");
     88         return;
     89     }
     90     sort(path.begin(),path.end(),greater<int>());
     91     printf("%d
    ",path[k-1]);
     92     return;
     93 }
     94 
     95 int main(){
     96     for(int i=0;i<maxm;++i)    _pow[i]=1<<i; //预处理2^n 
     97     int k,a,b;
     98     n=read();m=read();
     99     init();
    100     for(int i=1;i<=n;i++) val[i]=read();
    101     for(int i=0;i<n-1;++i){
    102         a=read(),b=read();
    103         add_edge(a,b);
    104         add_edge(b,a);
    105     }
    106     dfs(1,-1,0);
    107     rmq_init(2*n-1);
    108     for(int i=0;i<m;++i){
    109         k=read();a=read();b=read();
    110         if(k) solve(k,a,b);
    111         else val[a]=b;
    112     }
    113     
    114     return 0;
    115 }
  • 相关阅读:
    一款HTML5网页网络检测工具--LibreSpeed
    远程连接Linux中的Mysql数据库
    Ubuntu安装python-rrdtool模块
    Ubuntu 18.04 lxd和lxd-client导致版本过低无法apt安装
    7.JVM调优-方法区,堆,栈调优详解
    6.堆和GC
    5.java内存模型详细解析
    4.自定义类加载器实现及在tomcat中的应用
    3.代码实现自定义类加载器
    2.双亲委派机制详细解析及原理
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7471269.html
Copyright © 2011-2022 走看看