zoukankan      html  css  js  c++  java
  • 【bzoj4538】[Hnoi2016]网络

    我们考虑树剖,线段树上维护一个堆,保存不经过该段区间的路径的权值。 
    对于一条路径我们将对于线段树中的区间提取出来,在对于线段树中进行修改。也就是在堆中插入或删除。 
    对于一次询问,只要找到包含该点的线段中堆顶权值最大的就行了。

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<queue>
      8 using namespace std;
      9   
     10 typedef long long LL;
     11   
     12 #define N 200010
     13   
     14 struct data
     15 {
     16     int l,r;
     17 }q[N];
     18   
     19 struct edge
     20 {
     21     int s,to,next;
     22 }e[N<<1];
     23 int head[N<<1];
     24 int cnt;
     25   
     26 int dep[N],siz[N],son[N],top[N],pos[N];
     27 int fa[N][20],val[N<<2];
     28   
     29 bool vis[N];
     30   
     31 int n,m;
     32 int ans,res,num;
     33   
     34 int askd;
     35   
     36 struct cmp
     37 {
     38     bool operator() (int a,int b) 
     39     {
     40         return val[a]<val[b]; 
     41     }
     42 };
     43   
     44 priority_queue<int,vector<int>,cmp> Q[N<<2];
     45   
     46 bool cmp(data a,data b)
     47 {
     48     return a.l<b.l;
     49 }
     50   
     51 void link(int x,int y)
     52 {
     53     e[++cnt]=(edge){x,y,head[x]};
     54     head[x]=cnt;
     55 }
     56   
     57 void dfs(int x)
     58 {
     59     siz[x]=1;
     60     son[x]=0;
     61     for (int i=head[x];i;i=e[i].next)
     62     {
     63         int t=e[i].to;
     64         if (t!=fa[x][0])
     65         {
     66             dep[t]=dep[x]+1;
     67             fa[t][0]=x;
     68             dfs(t);
     69             siz[x]+=siz[t];
     70             if (siz[t]>siz[son[x]])
     71                 son[x]=t;
     72         }
     73     }
     74 }
     75   
     76 void dfs2(int x,int cha)
     77 {
     78     pos[x]=++res;
     79     top[x]=cha;
     80     if (son[x])
     81         dfs2(son[x],cha);
     82     for (int i=head[x];i;i=e[i].next)
     83     {
     84         int t=e[i].to;
     85         if (t!=fa[x][0] && t!=son[x])
     86             dfs2(t,t);
     87     }
     88 }
     89   
     90 void build_lca()
     91 {
     92     for (int j=1;j<=18;j++)
     93         for (int i=1;i<=n;i++)
     94             if (fa[i][j-1])
     95                 fa[i][j]=fa[fa[i][j-1]][j-1];
     96 }
     97   
     98 int lca(int x,int y)
     99 {
    100     if (dep[x]<dep[y])
    101         swap(x,y);
    102     int t=dep[x]-dep[y];
    103     for (int i=18;i>=0;i--)
    104         if (t & (1<<i))
    105             x=fa[x][i];
    106     if (x==y)
    107         return x;
    108     for (int i=18;i>=0;i--)
    109         if (fa[x][i]!=fa[y][i])
    110             x=fa[x][i],y=fa[y][i];
    111     return fa[x][0];
    112 }
    113   
    114 void add(int nowl,int nowr,int now,int l,int r,int d)
    115 {
    116     if (l<=nowl && nowr<=r)
    117     {
    118         Q[now].push(d);
    119         return ;
    120     }
    121     int mid=(nowl+nowr)>>1;
    122     if (l<=mid)
    123         add(nowl,mid,now<<1,l,r,d);
    124     if (r>=mid+1)
    125         add(mid+1,nowr,now<<1|1,l,r,d);
    126 }
    127   
    128 void query(int nowl,int nowr,int now,int d)
    129 {
    130     while (!Q[now].empty())
    131     {
    132         int k=Q[now].top();
    133         if (vis[k])
    134             Q[now].pop();
    135         else
    136         {
    137             num=max(num,val[k]);
    138             break;
    139         }
    140     }
    141     if (nowl==nowr)
    142         return ;
    143     int mid=(nowl+nowr)>>1;
    144     if (d<=mid)
    145         query(nowl,mid,now<<1,d);
    146     else
    147         query(mid+1,nowr,now<<1|1,d);
    148 }
    149 int main()
    150 {
    151     scanf("%d%d",&n,&m);
    152     int x,y;
    153     for (int i=1;i<n;i++)
    154     {
    155         scanf("%d%d",&x,&y);
    156         link(x,y);
    157         link(y,x);
    158     }
    159     dep[1]=1;
    160     dfs(1);
    161     dfs2(1,1);
    162     build_lca();
    163     for (int i=1;i<=m;i++)
    164     {
    165         scanf("%d",&askd);
    166         if (askd==0)
    167         {
    168             scanf("%d%d%d",&x,&y,&val[i]);
    169             int w=0,z=lca(x,y);
    170             while (dep[top[x]]>dep[z])
    171             {
    172                 q[++w]=(data){pos[top[x]],pos[x]};
    173                 x=fa[top[x]][0];
    174             }
    175             while (dep[top[y]]>dep[z])
    176             {
    177                 q[++w]=(data){pos[top[y]],pos[y]};
    178                 y=fa[top[y]][0];
    179             }
    180             if (x!=z)
    181                 q[++w]=(data){pos[z],pos[x]};
    182             else if (y!=z)
    183                 q[++w]=(data){pos[z],pos[y]};
    184             else
    185                 q[++w]=(data){pos[z],pos[z]};
    186             q[++w]=(data){n+1,n+1};
    187             sort(q+1,q+w+1,cmp);
    188             for (int j=1;j<=w;j++)
    189                 if (q[j-1].r<q[j].l-1)
    190                     add(1,n,1,q[j-1].r+1,q[j].l-1,i);
    191         }
    192         else if (askd==1)
    193         {
    194             scanf("%d",&x);
    195             vis[x]=1;
    196         }
    197         else
    198         {
    199             scanf("%d",&x);
    200             num=-1;
    201             query(1,n,1,pos[x]);
    202             printf("%d
    ",num);
    203         }
    204     }
    205     return 0;
    206 }
  • 相关阅读:
    python 单例模式
    JAVA基础知识总结
    java环境配置
    VScode输出中文乱码的解决方法------测试过可以用
    centos7 单独安装pip
    pyqt5信号与槽
    桌面程序显示到前台
    下载哔哩哔哩视频
    pyqt5 designer安装步骤
    树莓派配置静态wifi地址
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5491895.html
Copyright © 2011-2022 走看看