BZOJ2594 [Wc2006]水管局长数据加强版

删边变为反向加边,一开始开了数组记录了边的编号,结果往下一翻才发现数据是加强版只得log的求编号了。

两点间最大路径最小值一定在最小生成树上。

先从小到大加边,然后就是裸的LCT了。

By:大奕哥

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1500005;
  4 int c[N][2],mx[N],fa[N],w[N],pos[N],rev[N],s[N];
  5 int n,m,Q;
  6 bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
  7 void update(int x)
  8 {
  9     mx[x]=w[x];pos[x]=x;
 10     if(mx[x]<mx[c[x][0]])mx[x]=mx[c[x][0]],pos[x]=pos[c[x][0]];
 11     if(mx[x]<mx[c[x][1]])mx[x]=mx[c[x][1]],pos[x]=pos[c[x][1]];
 12     return;
 13 }
 14 void pushup(int x)
 15 {
 16     if(rev[x])
 17     {
 18         rev[x]^=1;rev[c[x][0]]^=1;rev[c[x][1]]^=1;
 19         swap(c[x][0],c[x][1]);
 20     }
 21     return;
 22 }
 23 void rotate(int x)
 24 {
 25     int y=fa[x],z=fa[y],l,r;
 26     l=c[y][1]==x;r=l^1;
 27     if(!isroot(y))c[z][c[z][1]==y]=x;
 28     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
 29     c[y][l]=c[x][r];c[x][r]=y;
 30     update(y);update(x);
 31     return;
 32 }
 33 void splay(int x)
 34 {
 35     int top=0,i;
 36     for(i=x;!isroot(i);i=fa[i])s[++top]=i;s[++top]=i;
 37     for(i=top;i;--i)pushup(s[i]);
 38     while(!isroot(x))
 39     {
 40         int y=fa[x],z=fa[y];
 41         if(!isroot(y))
 42         {
 43             if(c[y][0]==x^c[z][0]==y)rotate(x);
 44             else rotate(y);
 45         }
 46         rotate(x);
 47     }
 48     return;
 49 }
 50 void access(int x)
 51 {
 52     int y=0;
 53     while(x)
 54     {
 55         splay(x);
 56         c[x][1]=y;
 57         y=x;x=fa[x];
 58     }
 59     return;
 60 }
 61 void mroot(int x)
 62 {
 63     access(x);splay(x);rev[x]^=1;
 64 }
 65 void cut(int x,int y)
 66 {
 67     mroot(x);access(y);splay(y);c[y][0]=fa[x]=0;
 68 }
 69 void link(int x,int y)
 70 {
 71     mroot(x);fa[x]=y;splay(x);
 72 }
 73 int f[N];
 74 inline int get(int x)
 75 {
 76     return x==f[x]?x:f[x]=get(f[x]);
 77 }
 78 int query(int x,int y)
 79 {
 80     mroot(x);access(y);splay(y);
 81     return pos[c[y][0]];
 82 }
 83 
 84 struct node
 85 {
 86     int x,y,w,id,f;
 87     bool operator <(const node &b)const{
 88         return x<b.x||(x==b.x&&y<b.y);
 89     }
 90 }e[N];
 91 struct quer
 92 {
 93     int x,y,f,ans,id;
 94 }q[100005];
 95 bool cmp(node a,node b){
 96     return a.w<b.w;
 97 }
 98 bool cmp2(node a,node b){
 99     return a.id<b.id;
100 }
101 int find(int x,int y)
102 {
103     int l=1,r=m;
104     while(l<=r)
105     {
106         int mid=l+r>>1;
107         if(e[mid].x<x||(e[mid].x==x&&e[mid].y<y))l=mid+1;
108         else if(e[mid].x==x&&e[mid].y==y)return mid;
109         else r=mid-1;
110     }
111 }
112 int main()
113 {
114     scanf("%d%d%d",&n,&m,&Q);
115     for(int i=1;i<=n;++i)f[i]=i;
116     for(int i=1;i<=m;++i)
117     {
118         scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
119         if(e[i].y<e[i].x)swap(e[i].y,e[i].x);
120     }
121     sort(e+1,e+1+m,cmp);
122     for(int i=1;i<=m;++i)
123     {
124         e[i].id=i;
125         w[i+n]=e[i].w;
126         mx[i+n]=e[i].w;
127         pos[i+n]=i+n;
128     }
129     sort(e+1,e+1+m);
130     for(int i=1;i<=Q;++i)
131     {
132         scanf("%d%d%d",&q[i].f,&q[i].x,&q[i].y);
133         if(q[i].f==2)
134         {
135             if(q[i].x>q[i].y)swap(q[i].x,q[i].y);
136             int tmp=find(q[i].x,q[i].y);
137             e[tmp].f=1;q[i].id=e[tmp].id;
138         }
139     }
140     sort(e+1,e+1+m,cmp2);
141     for(int i=1;i<=m;++i)
142     {
143         if(e[i].f)continue;
144         int fx=get(e[i].x),fy=get(e[i].y);
145         if(fx!=fy)
146         {
147             f[fx]=fy;
148             link(e[i].x,i+n);link(e[i].y,i+n);
149         }
150     }
151     for(int i=Q;i;--i)
152     {
153         if(q[i].f==1)q[i].ans=w[query(q[i].x,q[i].y)];
154         else
155         {
156             int tmp=query(q[i].x,q[i].y);int k=q[i].id;
157             if(w[tmp]>e[k].w)
158             {
159                 cut(tmp,e[tmp-n].x);cut(tmp,e[tmp-n].y);
160                 link(k+n,e[k].x);link(k+n,e[k].y);
161             }
162         }
163     }
164     for(int i=1;i<=Q;++i)
165     {
166         if(q[i].f==1)printf("%d\n",q[i].ans);
167     }
168     return 0;
169 }

 

生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。
posted @ 2018-01-24 21:13  大奕哥&VANE  阅读(138)  评论(0编辑  收藏  举报