【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 }
原文地址:https://www.cnblogs.com/yangjiyuan/p/5491895.html