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 }
时间: 2024-11-06 07:09:47