zoukankan      html  css  js  c++  java
  • 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
    ",q[i].ans);
    167     }
    168     return 0;
    169 }
  • 相关阅读:
    机器学习笔记(一)线性回归模型
    为什么拷贝构造函数的参数可以直接去访问它自己的私有成员?
    C++之forward move源码分析
    C++之forward
    C++之不完整的数据类型释放
    C++中typename关键字的使用方法和注意事项(好文收藏)
    C++之左值引用和右值引用
    C++之Class内存
    C++ 之Const
    C++之DISALLOW_COPY_AND_ASSIGN
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8343591.html
Copyright © 2011-2022 走看看