首页 > 其他分享 >[WC2006] 水管局长 题解

[WC2006] 水管局长 题解

时间:2025-01-08 14:45:11浏览次数:1  
标签:int 题解 void WC2006 fa sn fl id 水管

最大值最小的路径肯定在最小生成树上,考虑用 \(LCT\) 维护最小生成树,只需要维护长度最长的边即可实现。由于 \(LCT\) 维护最小生成树不支持删边,所以采用倒序加边的方式处理。

时间复杂度 \(O(n\log n)\)。

#include<bits/stdc++.h>
#define fa(x) lct[x].fa
#define fl(x) lct[x].fl
#define id(x) lct[x].id
#define sn(x,i) lct[x].sn[i]
using namespace std;
const int N=1e5+5,M=1e6+N;
struct node{
    int sn[2],fa,fl,id;
}lct[M];int n,m,q,st[M],u[M],v[M],w[M];
int tp,mp[M],qo[N],qx[N],qy[N],ans[N];
unordered_map<int,int>ma[N];
int check(int x){
    return sn(fa(x),0)!=x&&sn(fa(x),1)!=x;
}int chksn(int x){
    return sn(fa(x),1)==x;
}void push_up(int x){
    id(x)=id(sn(x,(w[id(sn(x,0))]<w[id(sn(x,1))])));
    if(w[x]>w[id(x)]) id(x)=x;
}void push_down(int x){
    if(!x||!fl(x)) return;
    fl(sn(x,0))^=1,fl(sn(x,1))^=1;
    swap(sn(x,0),sn(x,1)),fl(x)=0;
}void rotate(int x){
    int y=fa(x),z=fa(y),k=chksn(x);
    if(!check(y))
        sn(z,chksn(y))=x;
    fa(x)=z,fa(y)=x,fa(sn(x,1-k))=y;
    sn(y,k)=sn(x,1-k),sn(x,1-k)=y;
    push_up(y);
}void splay(int x){
    st[tp=1]=x;
    for(int i=x;!check(i);i=fa(i)) st[++tp]=fa(i);
    while(tp) push_down(st[tp--]);
    while(!check(x)){
        int y=fa(x),z=fa(y);
        if(!check(y))
            rotate(chksn(x)!=chksn(y)?x:y);
        rotate(x);
    }push_up(x);
}void access(int x){
    for(int i=0;x;i=x,x=fa(x))
        splay(x),sn(x,1)=i,push_up(x);
}void mk(int x){
    access(x),splay(x),fl(x)^=1;
}void split(int x,int y){
    mk(x),access(y),splay(y);
}void cut(int x,int y){
    split(x,y),sn(y,0)=fa(x)=0;
}void link(int x,int y){
    mk(x),access(y),fa(x)=y;
}int find(int x){
    access(x),splay(x);
    while(sn(x,0)) x=sn(x,0);
    return x;
}void add(int x){
    if(find(u[x]+m)!=find(v[x]+m))
        return link(u[x]+m,x),link(x,v[x]+m);
    split(u[x]+m,v[x]+m);int idx=id(v[x]+m);
    if(w[idx]<=w[x]) return;
    cut(u[idx]+m,idx),cut(idx,v[idx]+m);
    link(u[x]+m,x),link(x,v[x]+m);
}int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m>>q;
    for(int i=1;i<=m;i++){
        cin>>u[i]>>v[i]>>w[i];
        ma[u[i]][v[i]]=ma[v[i]][u[i]]=i;
    }for(int i=1;i<=q;i++){
        cin>>qo[i]>>qx[i]>>qy[i];
        if(qo[i]==2) mp[ma[qx[i]][qy[i]]]=1;
    }for(int i=1;i<=m;i++) if(!mp[i]) add(i);
    for(int i=q;i;i--){
        if(qo[i]==1){
            split(qx[i]+m,qy[i]+m);
            ans[i]=w[id(qy[i]+m)];
        }else add(ma[qx[i]][qy[i]]);
    }for(int i=1;i<=q;i++)
        if(ans[i]) cout<<ans[i]<<"\n";
    return 0;
}

标签:int,题解,void,WC2006,fa,sn,fl,id,水管
From: https://www.cnblogs.com/chang-an-22-lyh/p/18659652/wc2006-shui_guan_ju_zhang-tj

相关文章

  • [Ynoi2016] 镜中的昆虫 题解
    [Ynoi2016]镜中的昆虫题解好题值得一做。题目大意:给一个序列,有若干个离线询问,每次可以区间推平或询问区间内的颜色个数,数据范围是\(10^5\)级别。解题思路:我们可以先考虑一个弱化版,每次是单点修改怎么做,类似于CF848C。我们考虑维护出每一个位置上一个与它相等的位置是\(p......
  • Luogu P2414 NOI2011 阿狸的打字机 题解 [ 紫 ] [ AC 自动机 ] [ 离线思想 ] [ 树状数
    阿狸的打字机:非常牛的AC自动机题。暴力先考虑在暴力的情况下,我们如何计算\(x\)匹配\(y\)的次数。显然,我们会模拟往\(y\)里加字符的过程,在此过程中做KMP进行匹配,统计答案。那么如果涉及多个模式串呢?就可以把KMP加强成AC自动机了。考虑在AC自动机上如何刻画这个......
  • CF2057E2 Another Exercise on Graphs (hard version) 题解
    感觉和[NOI2018]归程有点像(?考虑对每个询问二分答案,设二分到的答案是\(x\),要判断路径上的\(k\)大值是否能不大于\(x\),只需先将价值不大于\(x\)的所有边的边权设为\(0\),其他边设为\(1\),跑一遍\(a\)到\(b\)的最短路,看最短路长度是否不大于\(k\)即可。因为\(x\)的......
  • Luogu P3041 USACO12JAN Video Game G 题解 [ 紫 ] [ AC 自动机 ] [ 动态规划 ]
    VideoGamesG:弱智紫题,30min切了,dp思路非常板。多模式串一看肯定就是要建出AC自动机,然后在fail树里下传标记,预处理每个节点到达后的得分。然后设计\(dp_{i,j}\)表示第\(i\)个字符,AC自动机里匹配节点在\(j\)的最大答案,刷表法转移即可:\[dp_{i+1,ch_{j,c}}\gets\ma......
  • HDU7521 cats 的二分答案 题解
    思路首先,转换一下题意。只有在\(val=0\)时,才会向左缩小范围。然而只有越界访问才能达成\(val=0\),因此实际上我们最多只能向左缩小范围\(k\)次。对于当前的二分区间,\(mid\)本身可以作为一个答案,同时还要加上左右两边子区间的贡献。因此想到可以递归计算子区间的贡献。......
  • 题解- 恢复数组
    题目描述有一个数组a[1…n],但是这个数组的内容丢失了,你要尝试恢复它。已知以下的三个事实:1、对于1<=i<=n,都有a[i]>0,且所有的a[i]互不相同。即a数组保存的全部都是正整数,且互不相同。2、x和y一定是属于数组a,且x<y。3、a数组是递增的数组,且相邻两项的差是相等的。即数组a......
  • 海贼OJ #251. 士兵 题解 排序+中位数(数学思维题)
    题目链接:https://oj.haizeix.com/problem/251解题思路:最短总距离是所有点到中位数的距离之和。对\(y\):排序求中位数。对\(x\):对\(x\)排序,然后对排序后的\(x_i-i\)排序,然后求最短距离。对\(x_i-i\)进行处理,能保证最终的\(x_i\)各不一样且相邻。示例程序:#inclu......
  • 题解:P1541 [NOIP2010 提高组] 乌龟棋
    基础动态规划。这道题的题目条件显然满足阶段性和无后效性,那么有一个直观的思路就是把当前所处格子和四种卡片的使用次数作为状态。但是如果按照上面的想法,数组空间是无法开下的,所以我们稍微变一下思路,把四种卡片的使用数量作为状态,对于当前所处格子的话可以直接计算出来,这样数......
  • P8037 [COCI2015-2016#7] Prokletnik 题解
    题意定义一个区间$l,r$为好的当且仅当最小值为$a_l$且最大值为$a_r$或最大值为$a_l$且最小值为$a_r$。我们先考虑最小值为$a_l$且最大值为$a_r$的,另一个我们翻转过来在搞一遍就好了。先考虑将询问离线按$r$排序,容易发现,对于每个右端点$r$对应的合法左端点是......
  • E. Beautiful Array(题解)
    原题链接:https://codeforces.com/problemset/problem/1986/E思路:排序,取模,思维关于操作:ai=ai+k;若要使a1+m1*k==a2+m2*k;则当a1,a2满足a1%k==a2%k,a1,a2可以满足a1+m1*k==a2+m2*k;并在需要(|a1-a2|)/k次操作。将a数组取模后,用vector分别储存,a1和a2相差越小,需要的次数越......