zoukankan      html  css  js  c++  java
  • HDU 5266 pog loves szh III

    题目:pog loves szh III

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5266

    题意:给一棵树,有m个询问,每个询问问所有下标在[l, r]之中的结点的最近公共祖先。

    思路:

      线段树 + LCA

      这道题数据有点大,n、m均在30万,所以有点卡内存,做这道题才知道自己平时做题有多浪费内存。。。

      题目提示小心栈溢出,我AC以后再用普通的dfs试,发现不会出现该问题,但最好还是自己写栈,用while代替递归。

      题目思路并不难,线段树处理区间,建树时使用lca在线计算即可。

    AC代码:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<math.h>
      5 #include<set>
      6 #include<map>
      7 #include<list>
      8 #include<stack>
      9 #include<queue>
     10 #include<vector>
     11 #include<string>
     12 #include<iostream>
     13 #include<algorithm>
     14 using namespace std;
     15 #define lson rt<<1
     16 #define rson rt<<1|1
     17 #define N 300005
     18 #define M 300005
     19 #define Mod 1000000007
     20 #define LL long long
     21 #define INF 0x7fffffff
     22 vector<int> e[M];
     23 int xu[N*2],xo,pos[M],h[M];
     24 
     25 struct SSS
     26 {
     27   int rt,fa;
     28   int i;
     29 };
     30 
     31 void dfs(int rt,int fa,int ceng)  //普通递归
     32 {
     33   h[rt]=ceng;
     34   for(int i=0;i<e[rt].size();i++)
     35   {
     36     if(e[rt][i]!=fa) dfs(e[rt][i],rt,ceng+1);
     37     pos[rt]=xo;
     38     xu[xo++]=rt;
     39   }
     40 }
     41 
     42 SSS st[M];
     43 void dfs(int rt)  //while型递归
     44 {
     45   int top=0;
     46   st[top].rt=rt;
     47   st[top].fa=-1;
     48   st[top].i=0;
     49   h[rt]=1;
     50   top++;
     51   while(top)
     52   {
     53     SSS a=st[top-1];
     54     st[top-1].i++;
     55     if(a.i<e[a.rt].size())
     56     {
     57       int ad=e[a.rt][a.i];
     58       if(ad!=a.fa)
     59       {
     60         h[ad]=h[a.rt]+1;
     61         st[top].rt=ad;
     62         st[top].fa=a.rt;
     63         st[top++].i=0;
     64       }
     65       if(a.i!=0) xu[xo++]=a.rt;
     66     }
     67     else
     68     {
     69       pos[a.rt]=xo;
     70       xu[xo++]=a.rt;
     71       top--;
     72     }
     73   }
     74 }
     75 int f[N<<1][24];
     76 void rmq()
     77 {
     78   for(int j=0;j<xo;j++) f[j][0]=xu[j];
     79   for(int i=1;i<24;i++)
     80   {
     81     for(int j=0;j<xo;j++)
     82     {
     83       if(j+(1<<i)-1 < xo)
     84       {
     85         if(h[f[j][i-1]]<h[f[j+(1<<i-1)][i-1]])
     86         {
     87           f[j][i]=f[j][i-1];
     88         }
     89         else
     90         {
     91           f[j][i]=f[j+(1<<i-1)][i-1];
     92         }
     93       }
     94     }
     95   }
     96 }
     97 int look(int l,int r)
     98 {
     99   if(l>r) l^=r^=l^=r;
    100   int k=(int)log2((double)(r-l+1));
    101   if(h[f[l][k]]<h[f[r-(1<<k)+1][k]]) return f[l][k];
    102   else return f[r-(1<<k)+1][k];
    103 }
    104 
    105 int v[M<<2];
    106 void build(int l,int r,int rt)
    107 {
    108   if(l==r)
    109   {
    110     v[rt]=l;
    111     return ;
    112   }
    113   build(l,(l+r)/2,rt<<1);
    114   build((l+r)/2+1,r,rt<<1|1);
    115   v[rt] = look(pos[v[rt<<1]],pos[v[rt<<1|1]]);
    116 }
    117 int query(int ll,int rr,int l,int r,int rt)
    118 {
    119   if(l==ll&&r==rr) return v[rt];
    120   int mid=(ll+rr)/2;
    121   if(l>mid) return query(mid+1,rr,l,r,rt<<1|1);
    122   else if(r<=mid) return query(ll,mid,l,r,rt<<1);
    123   else return look(pos[query(ll,mid,l,mid,rt<<1)],pos[query(mid+1,rr,mid+1,r,rt<<1|1)]);
    124 }
    125 int main()
    126 {
    127   int x,y,n,m;
    128   while(scanf("%d",&n)!=EOF)
    129   {
    130     for(int i=1;i<=n;i++)
    131     {
    132       e[i].clear();
    133       h[i]=INF;
    134     }
    135     for(int i=1;i<n;i++)
    136     {
    137       scanf("%d%d",&x,&y);
    138       e[x].push_back(y);
    139       e[y].push_back(x);
    140     }
    141     xo=0;
    142     dfs(1,-1,1);
    143     rmq();
    144     build(1,n,1);
    145     scanf("%d",&m);
    146     while(m--)
    147     {
    148       scanf("%d%d",&x,&y);
    149       printf("%d
    ",query(1,n,x,y,1));
    150     }
    151   }
    152   return 0;
    153 }

     

  • 相关阅读:
    Vue|提示信息统一处理
    SpringBoot|封装接口实现自动创建job并且自动构建功能
    SpringBoot|自动创建job并且参数化构建
    SpringBoot|持久化常用注解
    SpringBoot|使用mybatis-generator-maven-plugin自动生成代码
    SpringBoot|config.properties通用Mapper配置
    SpringBoot|config.properties通用数据库连接配置
    SpringBoot|数据持久化技术现状
    Debian安装完成后没有无线网络的解决方法
    Debian系统设置terminal快捷键
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/6028002.html
Copyright © 2011-2022 走看看