【bzoj】4538: [Hnoi2016]网络

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4538


维护一个数据结构支持对于一颗树的操作,需要支持:

1.对于树上的一条路径上的每个点上放一个值。

2.撤销某次操作的路劲放。

3.查询除了经过这个点的路径的最大值。


往一个路径上丢值相当于往不经过条路径的所有点上丢值。

用一个树链剖分即可维护,对于操作区间取反。

直接查询单点最大值即可。

为了维护单点最大值,线段树中的每一个点对应两个堆,用于维护插入誉删除。

防止爆空间,所以标记永久化即可。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<vector>
  5 #include<cstdlib>
  6 #include<cmath>
  7 #include<cstring>
  8 #include<queue>
  9 using namespace std;
 10 #define maxn 400100
 11 #define llg int
 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
 13 llg n,m,tail,deep[maxn],top[maxn],size[maxn],son[maxn],dad[maxn],id[maxn],dfsn,T,type;
 14 vector<llg>a[maxn];
 15 
 16 struct node
 17 {
 18     priority_queue<llg>q1,q2;
 19     
 20     void push1(llg x){ q1.push(x);}
 21     void push2(llg x){ q2.push(x);}
 22 
 23     llg top()
 24     {
 25         llg anss=-1;
 26         while (!q2.empty() && (q2.top()==q1.top())) q1.pop(),q2.pop();
 27         if (!q1.empty()) anss=q1.top();
 28         return anss;
 29     }
 30 }val[maxn*4];
 31 
 32 struct data
 33 {
 34     llg l,r;
 35 }dl[maxn];
 36 
 37 struct data_
 38 {
 39     llg x,y,z;
 40 }ask[maxn];
 41 
 42 bool cmp(const data&a,const data&b) {return a.l<b.l;}
 43 
 44 void init()
 45 {
 46     llg x,y;
 47     cin>>n>>m;
 48     for (llg i=1;i<n;i++)
 49     {
 50         scanf("%d%d",&x,&y);
 51         a[x].push_back(y),a[y].push_back(x);
 52     }    
 53 }
 54 
 55 void dfs_1(llg x,llg fa)
 56 {
 57     size[x]=1;
 58     llg w=a[x].size(),v;
 59     for (llg i=0;i<w;i++)
 60     {
 61         v=a[x][i];
 62         if (v==fa) continue;
 63         deep[v]=deep[x]+1;
 64         dfs_1(v,x);
 65         dad[v]=x; size[x]+=size[v];  
 66         if (size[v]>size[son[x]]) son[x]=v;
 67     }
 68 }
 69 
 70 void dfs_2(llg x,llg fa)
 71 {
 72     id[x]=++dfsn;
 73     if (son[x]) {top[son[x]]=top[x]; dfs_2(son[x],x);}
 74     llg w=a[x].size(),v;
 75     for (llg i=0;i<w;i++)
 76     {
 77         v=a[x][i];
 78         if (v==fa || v==son[x]) continue;
 79         top[v]=v; dfs_2(v,x);
 80     }
 81 }
 82 
 83 void add(llg o,llg l,llg r,llg L,llg R,llg V)
 84 {
 85     if (l>=L && r<=R)
 86     {
 87         if (T) val[o].push1(V);
 88         else val[o].push2(V);
 89         return ;
 90     }
 91     llg lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
 92     if (L<=mid) add(lc,l,mid,L,R,V);
 93     if (R>mid) add(rc,mid+1,r,L,R,V);
 94 }
 95 
 96 void solve(llg x,llg y,llg V)
 97 {
 98     llg f1=top[x],f2=top[y];
 99     tail=0;
100     while (f1!=f2)
101     {
102         if (deep[f1]<deep[f2]) swap(x,y),swap(f1,f2);
103         dl[++tail].l=id[f1]; dl[tail].r=id[x];
104         x=dad[f1]; f1=top[x];
105     }
106     if (deep[x]<deep[y]) swap(x,y);
107     dl[++tail].l=id[y],dl[tail].r=id[x];
108     sort(dl+1,dl+tail+1,cmp);
109     llg l=0,r,last=0;
110     for (llg i=1;i<=tail;i++)
111     {
112         l=last+1; r=dl[i].l-1;
113         if (l<=r) add(1,1,n,l,r,V);
114         last=dl[i].r;
115     }
116     l=last+1; r=n;
117     if (l<=r) add(1,1,n,l,r,V);
118 }
119 
120 llg maxl_(llg o,llg l,llg r,llg wz)
121 {
122     llg ans=val[o].top();
123     if (l==r) return ans;
124     llg mid=(l+r)>>1,lc=o<<1,rc=o<<1|1;
125     if (wz<=mid) ans=max(ans,maxl_(lc,l,mid,wz));
126     if (wz>mid) ans=max(ans,maxl_(rc,mid+1,r,wz));
127     return ans;
128 }
129 
130 int main()
131 {
132     yyj("a");
133     init();
134     dfs_1(1,-1);
135     top[1]=1;
136     dfs_2(1,-1);
137     for (llg o=1;o<=m;o++)
138     {
139         scanf("%d",&type);
140         if (type==0)
141         {
142             scanf("%d%d%d",&ask[o].x,&ask[o].y,&ask[o].z);
143             T=1;
144             solve(ask[o].x,ask[o].y,ask[o].z);
145         }
146         if (type==1)
147         {
148             llg x;
149             scanf("%d",&x);
150             T=0;
151             solve(ask[x].x,ask[x].y,ask[x].z);
152         }
153         if (type==2)
154         {
155             llg x;
156             scanf("%d",&x);
157             printf("%d
",maxl_(1,1,n,id[x]));
158         }
159     }
160     return 0;
161 }

本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
原文地址:https://www.cnblogs.com/Dragon-Light/p/6399283.html