• BZOJ2843


    Portal

    Description

    给出(n(nleq3 imes10^4))个独立的带权顶点,对其进行(m(mleq10^5))次操作:

    • 连接两个不连通的节点。如果它们已经联通,输出no
    • 更改单点的权值。
    • 求路径((u,v))上的点权和。如果它们不连通,输出impossible

    Solution

    一道link/cut tree裸题啦。

    Code

    //极地旅行社
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int const N=3e4+10;
    int n,m;
    int pre[N];
    int find(int x) {return pre[x]==x?x:pre[x]=find(pre[x]);}
    int fa[N],ch[N][2],val[N],sum[N]; bool rev[N];
    int wh(int p) {return ch[fa[p]][1]==p;}
    bool notRt(int p) {return p!=0&&ch[fa[p]][wh(p)]==p;}
    void rever(int p) {rev[p]^=1; swap(ch[p][0],ch[p][1]);}
    void update(int p) {sum[p]=val[p]+sum[ch[p][0]]+sum[ch[p][1]];}
    void pushdw(int p) {if(rev[p]) rever(ch[p][0]),rever(ch[p][1]),rev[p]=0;}
    void rotate(int p)
    {
        int q=fa[p],r=fa[q],w=wh(p);
        fa[p]=r; if(notRt(q)) ch[r][wh(q)]=p;
        fa[ch[q][w]=ch[p][w^1]]=q;
        fa[ch[p][w^1]=q]=p;
        update(q); update(p);
    }
    void pushdwRt(int p) {if(notRt(p)) pushdwRt(fa[p]); pushdw(p);}
    void splay(int p)
    {
        pushdwRt(p);
        for(int q=fa[p];notRt(p);rotate(p),q=fa[p]) if(notRt(q)) rotate(wh(p)==wh(q)?q:p);
        update(p);
    }
    void access(int p) {for(int q=0;p;q=p,p=fa[p]) splay(p),ch[p][1]=q,update(p);}
    void makeRt(int p) {access(p); splay(p),rever(p);}
    void link(int p,int q) {makeRt(p); fa[p]=q; pre[find(p)]=find(q);}
    int query(int p,int q) {makeRt(p),access(q); splay(q); return sum[q];}
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&val[i]),sum[i]=val[i];
        scanf("%d",&m);
        for(int i=1;i<=n;i++) pre[i]=i;
        for(int i=1;i<=m;i++)
        {
            char opt[15]; int x,y;
            scanf("%s",opt); scanf("%d%d",&x,&y);
            if(opt[0]=='b')
                if(find(x)==find(y)) puts("no");
                else link(x,y),puts("yes");
            else if(opt[0]=='p') val[x]=y,splay(x);
            else if(opt[0]=='e')
            {
                if(find(x)==find(y)) printf("%d
    ",query(x,y));
                else printf("impossible
    ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    趣味算法:国王和100个囚犯(据说是腾讯的面试题)
    限制文本框的输入(兼容FF,IE)
    切换家里和公司网络的脚本
    onchange,onpropertychange,oninput的使用
    正则匹配html标记
    javascript清空数组的三种方法
    正则查找重复
    (正则)提取页面里的img标签
    javascript类型检测(转载)
    查看sqlserver信息
  • 原文地址:https://www.cnblogs.com/VisJiao/p/BZOJ2843.html
Copyright © 2020-2023  润新知