码迷,mamicode.com
首页 > 其他好文 > 详细

HNOI2016 网络 (BZOJ4538)

时间:2016-05-03 12:11:52      阅读:338      评论:0      收藏:0      [点我收藏+]

标签:

HNOI2016 Day1 T2 网络

 

题意:给定一棵树,然后有若干个操作,可以新添加一条从u到v的权值为w的路径,或者将之前的一条路径删掉,动态询问不经过某个点的路径的最大权值

 

正解:树链剖分+线段树+堆

 

考场上面打了一个裸裸的树链剖分,连线段树都没套,复杂度是O(m^2 logn)的。当时真是傻了,只要套一个堆就可以AC了。。。我真傻,真的

首先考虑先树链剖分,然后看怎么处理这三个操作

显然题目要求我们动态维护不经过一个点的最大路径权值,那么我们就考虑用堆

每个线段树的结点里面存两个堆,都是大根堆,分别维护所有的入过堆的元素和已经被删除的元素,当我们需要求堆顶元素时,只需看一下两个堆的堆顶元素是否相等,相等的话顺便同时删掉,直到找到一个不相等的或者堆为空,就返回堆顶元素。这样就可以避免了如何删除路径的尴尬问题。

 

接着当我们插入路径的时候,显然树链剖分沿着重链往上跳的时候可以把经过的连续路径存下来。然后我们对于这些路径取反,把取反后的路径(即跳的过程中没有经过的点集或线段集)他们的线段树的堆中加入当前需要插入路径的权值。如果是删除的话,往删除堆里加入元素就可以了。

 

至于查询,就是找到之后一路往上跳,然后取一个MAX就可以了(找不到返回-1)。

 

  1 //It is made by jump~
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <vector>
  9 #include <queue>
 10 #include <map>
 11 using namespace std;
 12 typedef long long LL;
 13 const int MAXN = 100011;
 14 const int MAXM = 400011;
 15 int n,m;
 16 int first[MAXN],next[MAXN*2],to[MAXN*2];
 17 int ecnt;
 18 int q1[MAXM],q2[MAXM],q3[MAXM];
 19 
 20 int father[MAXN],top[MAXN],pson[MAXN],siz[MAXN],id[MAXN],deep[MAXN];
 21 
 22 //树链剖分+ 线段树维护堆
 23 
 24 struct qqueue{
 25     priority_queue<int>a,b;
 26     void push(int x) { a.push(x); }
 27     void del(int x) { b.push(x); }
 28     int top(){
 29     while(!b.empty() && a.top()==b.top()) a.pop(),b.pop();
 30     if(a.empty()) return -1;
 31     return a.top();
 32     }
 33 }jump[MAXN*4];
 34 
 35 struct E{
 36     int l,r;
 37 }line[MAXM];//维护线段取反后的两个端点
 38 
 39 inline int getint()
 40 {
 41        int w=0,q=0;
 42        char c=getchar();
 43        while((c<0 || c>9) && c!=-) c=getchar();
 44        if (c==-)  q=1, c=getchar();
 45        while (c>=0 && c<=9) w=w*10+c-0, c=getchar();
 46        return q ? -w : w;
 47 }
 48 
 49 inline void link(int x,int y){
 50     next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y;
 51     next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x;
 52 }
 53 
 54 inline void dfs1(int x,int fa){
 55     siz[x]=1;
 56     for(int i=first[x];i;i=next[i]) {
 57     int v=to[i];
 58     if(v==fa) continue;
 59     father[v]=x; deep[v]=deep[x]+1; dfs1(v,x);
 60     siz[x]+=siz[v]; if(siz[v]>siz[pson[x]]) pson[x]=v;
 61     }
 62 }
 63 
 64 inline void dfs2(int x,int fa){
 65     id[x]=++ecnt; 
 66     if(pson[x]) top[pson[x]]=top[x],dfs2(pson[x],x);
 67     for(int i=first[x];i;i=next[i]) {
 68     int v=to[i];
 69     if(v==fa || v==pson[x]) continue;
 70     top[v]=v;
 71     dfs2(v,x);      
 72     }
 73 }
 74 
 75 bool cmp(E q,E qq) { if(q.l==qq.l) return q.r<qq.r;  return q.l<qq.l; }
 76 
 77 inline void geng(int root,int l,int r,int ql,int qr,int val,int type){
 78     if(ql>qr) return ;
 79     if(ql==l && qr==r) {
 80     if(type==1) jump[root].push(val); 
 81     else jump[root].del(val);
 82     return ;
 83     }
 84     int mid=l+(r-l)/2; int lc=root*2,rc=lc+1;
 85     if(ql<=mid) geng(lc,l,mid,ql,min(qr,mid),val,type);
 86     if(qr>mid) geng(rc,mid+1,r,max(ql,mid+1),qr,val,type);
 87 }
 88 
 89 inline void update(int x,int y,int z,int type){
 90     int f1=top[x],f2=top[y];
 91     ecnt=0;
 92     while(f1!=f2) {
 93     if(deep[f1]<deep[f2]) swap(x,y),swap(f1,f2);
 94     line[++ecnt].l=id[f1]; line[ecnt].r=id[x];
 95     x=father[f1]; f1=top[x];
 96     }
 97     if(deep[x]<deep[y]) swap(x,y);
 98     line[++ecnt].l=id[y]; line[ecnt].r=id[x];
 99 
100     sort(line+1,line+ecnt+1,cmp);
101     int nowl=1;
102     for(int i=1;i<=ecnt;i++) {
103     geng(1,1,n,nowl,line[i].l-1,z,type);
104     nowl=line[i].r+1;
105     }
106     geng(1,1,n,nowl,n,z,type);
107 }
108 
109 inline int query(int root,int l,int r,int x){
110     if(l==r) return jump[root].top();
111     int mid=l+(r-l)/2; int lc=root*2,rc=lc+1;
112     if(x<=mid) return max(jump[root].top(),query(lc,l,mid,x));
113     else return max(jump[root].top(),query(rc,mid+1,r,x));
114 }
115 
116 inline void solve(){
117     for(int i=1;i<=n;i++) top[i]=1;
118     for(int i=1;i<=n;i++) siz[i]=n-i+1;
119     for(int i=1;i<=n-1;i++) pson[i]=i+1;
120     for(int i=1;i<=n;i++) deep[i]=id[i]=i;
121     for(int i=2;i<=n;i++) father[i]=i-1;
122 }
123 
124 int main()
125 {
126   n=getint();m=getint();
127   int x,y,type;
128   for(int i=1;i<n;i++) {
129       x=getint(),y=getint();
130       link(x,y);
131   }
132 
133   if(to[first[1]]==2) solve();
134 
135   deep[1]=1; dfs1(1,0); 
136   top[1]=1; ecnt=0; dfs2(1,0);
137 
138   for(int i=1;i<=m;i++) {
139       type=getint();
140       if(type==0) {
141       q1[i]=getint(); q2[i]=getint(); q3[i]=getint();
142       update(q1[i],q2[i],q3[i],1);
143       }
144       else if(type==1) {
145       q1[i]=getint();
146       update(q1[q1[i]],q2[q1[i]],q3[q1[i]],0);
147       }
148       else {
149       q1[i]=getint();
150       printf("%d\n",query(1,1,n,id[ q1[i] ]));
151       }
152   }
153   return 0;
154 }

 

HNOI2016 网络 (BZOJ4538)

标签:

原文地址:http://www.cnblogs.com/ljh2000-jump/p/5454437.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!