zoukankan      html  css  js  c++  java
  • UOJ_274_[清华集训2016]温暖会指引我们前行_LCT

    UOJ_274_[清华集训2016]温暖会指引我们前行_LCT

    任务描述:http://uoj.ac/problem/274


    本题中的字典序不同在于空串的字典序最大。

    并且题中要求排序后字典序最大

    因此我们要求的路径一定是最大生成树上的路径。

    于是变成了LCT模板题,动态维护最大生成树即可。

    注意每次find可能会T,于是我又写了个并查集...

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define RR register
    inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        RR int x=0; RR char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    inline char rc() {
        RR char s=nc();
        while(s<'a'||s>'z') s=nc();
        return s;
    }
    #define ls ch[p][0]
    #define rs ch[p][1]
    #define get(x) (ch[f[x]][1]==x)
    #define isrt(x) (ch[f[x]][1]!=x&&ch[f[x]][0]!=x)
    #define N 1000050
    int ch[N][2],f[N],sum[N],mn[N],t[N],l[N],rev[N],n,m,xx[N],yy[N],fa[N];
    char opt[10];
    int find(int x) {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    inline void pushup(int p) {
        sum[p]=sum[ls]+sum[rs]+l[p];
        mn[p]=p;
        if(t[mn[ls]]<t[mn[p]]) mn[p]=mn[ls];
        if(t[mn[rs]]<t[mn[p]]) mn[p]=mn[rs];
    }
    inline void pushdown(int p) {
        if(rev[p]) {
            swap(ch[ls][0],ch[ls][1]);
            swap(ch[rs][0],ch[rs][1]);
            rev[ls]^=1; rev[rs]^=1; rev[p]=0;
        }
    }
    void rotate(int x) {
        int y=f[x],z=f[y],k=get(x);
        if(!isrt(y)) ch[z][ch[z][1]==y]=x;
        ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
        ch[x][!k]=y; f[y]=x; f[x]=z;
        pushup(y); pushup(x);
    }
    void update(int p) {
        if(!isrt(p)) update(f[p]);
        pushdown(p);
    }
    void splay(int x) {
        update(x);
        for(int fa;fa=f[x],!isrt(x);rotate(x))
            if(!isrt(fa))
                rotate(get(fa)==get(x)?fa:x);
    }
    void access(int p) {
        int t=0;
        while(p) {
            splay(p);
            rs=t;
            pushup(p);
            t=p;
            p=f[p];
        }
    }
    void makeroot(int p) {
        access(p); splay(p); swap(ls,rs); rev[p]^=1;
    }
    void link(int x,int p) {
        makeroot(x); splay(p); f[x]=p;
    }
    void cut(int x,int p) {
        makeroot(x); access(p); splay(p); f[x]=ls=0; 
    }
    int querymin(int x,int p) {
        makeroot(x); access(p); splay(p); return mn[p];
    }
    int qlen(int x,int p) {
        makeroot(x); access(p); splay(p); return sum[p];
    }
    int main() {
        n=rd(); m=rd();
        int i,x,y,z,w,id;
        for(i=0;i<=n;i++) t[i]=1<<30,mn[i]=i,fa[i]=i;
        while(m--) {
            opt[0]=rc();
            if(opt[0]=='f') {
                id=rd(); x=rd(); y=rd(); z=rd(); w=rd();
                id++; x++; y++; 
                t[id+n]=z; l[id+n]=w; mn[id+n]=id+n; xx[id]=x; yy[id]=y;
                int dx=find(x),dy=find(y);
                if(dx==dy) {
                    int tmp=querymin(x,y);
                    if(t[tmp]>=z) continue;
                    cut(xx[tmp-n],tmp); cut(yy[tmp-n],tmp);
                }else fa[dx]=dy;
                link(id+n,x); link(id+n,y);
            }else if(opt[0]=='m') {
                x=rd(); y=rd(); x++; y++;
                int ans=find(x)==find(y)?qlen(x,y):-1;
                printf("%d
    ",ans);
            }else {
                id=rd(); z=rd(); id++;
                access(id+n); splay(id+n); l[id+n]=z; pushup(id+n);
            }
        }
    }
    
  • 相关阅读:
    Netty实现Http客户端
    Netty实现Http服务端
    Netty实现Tcp客户端
    Netty实现Tcp服务端
    MySQL进阶系列:一文详解explain
    spring boot 获取运行时的yml里的active配置
    eureka 注册中心添加认证
    zuul 负载
    jenkins spring cloud
    秒杀系统如何设计?
  • 原文地址:https://www.cnblogs.com/suika/p/9062687.html
Copyright © 2011-2022 走看看