• bzoj3159 决战


    题目描述:

    bz

    咕了几个月的题解:

    无脑$splay$+树剖。

    论复制粘贴在考场上拉分的重要作用。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 50050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,m,Rt,hed[N],cnt;
    struct EG
    {
        int to,nxt;
    }e[N<<1];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    int dep[N],siz[N],tp[N],son[N],fa[N],tin[N],tout[N],tim,pla[N];
    void dfs1(int u,int f)
    {
        fa[u]=f,siz[u]=1,dep[u]=dep[f]+1;
        for(int j=hed[u],to;j;j=e[j].nxt)if((to=e[j].to)!=f)
        {
            dfs1(to,u),siz[u]+=siz[to];
            if(siz[to]>siz[son[u]])son[u]=to;
        }
    }
    void dfs2(int u,int Top)
    {
        tp[u]=Top,tin[u]=++tim,pla[tim]=u;
        if(son[u])
        {
            dfs2(son[u],Top);
            for(int j=hed[u],to;j;j=e[j].nxt)
                if((to=e[j].to)!=fa[u]&&to!=son[u])dfs2(to,to);
        }
        tout[u]=tim;
    }
    int get_lca(int x,int y)
    {
        while(tp[x]!=tp[y])
        {
            if(dep[tp[x]]<dep[tp[y]])swap(x,y);
            x = fa[tp[x]];
        }
        return dep[x]<dep[y]?x:y;
    }
    struct Splay
    {
        int w[N],mx[N],mn[N],rt,rtt,fa[N],ch[N][2],siz[N];
        ll tag[N],s[N];
        bool res[N];
        void add(int u,ll d)
        {
            if(u)w[u]+=d,tag[u]+=d,s[u]+=d*siz[u],mx[u]+=d,mn[u]+=d;
        }
        void rever(int u)
        {
            if(u)swap(ch[u][0],ch[u][1]),res[u]^=1;
        }
        void pushdown(int u)
        {
            if(tag[u])
            {
                add(ch[u][0],tag[u]);
                add(ch[u][1],tag[u]);
                tag[u]=0;
            }
            if(res[u])
            {
                rever(ch[u][0]);
                rever(ch[u][1]);
                res[u] = 0;
            }
        }
        void update(int x)
        {
            s[x]=s[ch[x][0]]+s[ch[x][1]]+w[x];
            siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
            mx[x]=max(w[x],max(mx[ch[x][0]],mx[ch[x][1]]));
            mn[x]=min(w[x],min(mn[ch[x][0]],mn[ch[x][1]]));
        }
        void rotate(int x)
        {
            int y = fa[x],z = fa[y],k = (ch[y][1]==x);
            ch[z][ch[z][1]==y]=x,fa[x]=z;
            ch[y][k]=ch[x][!k],fa[ch[x][!k]]=y;
            ch[x][!k]=y,fa[y]=x;
            update(y),update(x);
        }
        int sta[N],tl;
        void down(int x)
        {
            tl = 0;
            while(x)sta[++tl]=x,x=fa[x];
            while(tl)pushdown(sta[tl--]);
        }
        void splay(int x,int goal)
        {
            down(x);
            while(fa[x]!=goal)
            {
                int y = fa[x],z = fa[y];
                if(z!=goal)
                    (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
                rotate(x);
            }
            if(!goal)rt=x;
        }
        void splayy(int x,int goal)
        {
            down(x);
            while(fa[x]!=goal)
            {
                int y = fa[x],z = fa[y];
                if(z!=goal)
                    (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
                rotate(x);
            }
            if(!goal)rtt=x;
        }
        int build(int l,int r,int f)
        {
            if(l>r)return 0;
            int mid = (l+r)>>1;
            fa[mid] = f;if(!f)rt=mid;
            ch[mid][0] = build(l,mid-1,mid);
            ch[mid][1] = build(mid+1,r,mid);
            update(mid);return mid;
        }
        void init()
        {
            fa[n+4]=n+3;ch[n+3][1]=n+4;rtt=n+3;
            siz[n+3]=2,siz[n+4]=1;
            mn[0]=0x3f3f3f3f,mx[0]=-0x3f3f3f3f;
        }
        int get_kth(int u,int k)
        {
            pushdown(u);
            int tmp = siz[ch[u][0]];
            if(k<=tmp)return get_kth(ch[u][0],k);
            else if(k==tmp+1)return u;
            else return get_kth(ch[u][1],k-1-tmp);
        }
        void split(int l,int r)
        {
            l = get_kth(rt,l),r = get_kth(rt,r+2);
            splay(l,0),splay(r,l);
        }
        void splitt(int l,int r)
        {
            l = get_kth(rtt,l),r = get_kth(rtt,r+2);
            splayy(l,0),splayy(r,l);
        }
        int get_kw(int k)
        {
            int x = get_kth(rt,k+1);return w[x];
        }
        ll get_sum(int l,int r)
        {
            split(l,r);
            return s[ch[ch[rt][1]][0]];
        }
        int get_max(int l,int r)
        {
            split(l,r);return mx[ch[ch[rt][1]][0]];
        }
        int get_min(int l,int r)
        {
            split(l,r);return mn[ch[ch[rt][1]][0]];
        }
        void Inc(int l,int r,int d)
        {
            split(l,r);
            add(ch[ch[rt][1]][0],d);
            update(ch[rt][1]),update(rt);
        }
        void mr(int l,int r)
        {
            split(l,r);int now = get_kth(rtt,2),las = ch[ch[rt][1]][0];
            splayy(now,0);fa[las]=n+3,ch[n+3][1]=las,ch[ch[rt][1]][0]=0;
            update(ch[rt][1]),update(rt),update(n+3),update(now);
        }
        void rvs()
        {
            splayy(n+3,0),splayy(n+4,n+3);
            rever(ch[ch[rtt][1]][0]);
        }
        void ml(int l,int r)
        {
            int xl = get_kth(rt,l),xr = get_kth(rt,l+1);
            splay(xr,0),splay(xl,xr);
            splitt(1,r-l+1);int now = ch[ch[rtt][1]][0];
            ch[ch[rtt][1]][0]=0,ch[ch[rt][0]][1]=now,fa[now]=ch[rt][0];
            update(ch[rt][0]),update(rt),update(ch[rtt][1]),update(rtt);
        }
    }tr;
    char op[10];
    int lst[N],rst[N],tl;
    ll queryS(int x,int y)
    {
        ll ret = 0;
        while(tp[x]!=tp[y])
        {
            ret+=tr.get_sum(tin[tp[x]],tin[x]);
            x = fa[tp[x]];
        }
        return ret+tr.get_sum(tin[y],tin[x]);
    }
    int queryMax(int x,int y)
    {
        int ret = -0x3f3f3f3f;
        while(tp[x]!=tp[y])
        {
            ret = max(ret,tr.get_max(tin[tp[x]],tin[x]));
            x = fa[tp[x]];
        }
        return max(ret,tr.get_max(tin[y],tin[x]));
    }
    int queryMin(int x,int y)
    {
        int ret = 0x3f3f3f3f;
        while(tp[x]!=tp[y])
        {
            ret = min(ret,tr.get_min(tin[tp[x]],tin[x]));
            x = fa[tp[x]];
        }
        return min(ret,tr.get_min(tin[y],tin[x]));
    }
    int main()
    {
        read(n),read(m),read(Rt);
        for(int i=1,u,v;i<n;i++)
        {
            read(u),read(v);
            ae(u,v),ae(v,u);
        }
        dfs1(Rt,0),dfs2(Rt,Rt);
        tr.build(1,n+2,0);tr.init();
        for(int i=1,x,y,w;i<=m;i++)
        {
            scanf("%s",op+1),read(x),read(y);
            if(dep[x]>dep[y])swap(x,y);
            if(op[1]=='I'&&op[3]=='c')
            {
                read(w);
                while(tp[y]!=tp[x])
                { 
                    tr.Inc(tin[tp[y]],tin[y],w);
                    y = fa[tp[y]];
                }
                tr.Inc(tin[x],tin[y],w);
            }else if(op[1]=='I'&&op[3]=='v')
            {
                tl = 0;
                while(tp[y]!=tp[x])
                {
                    lst[++tl]=tin[tp[y]],rst[tl]=tin[y];
                    tr.mr(lst[tl],rst[tl]);
                    y = fa[tp[y]];
                }
                lst[++tl]=tin[x],rst[tl]=tin[y];
                tr.mr(lst[tl],rst[tl]);
                tr.rvs();
                for(int j=tl;j>=1;j--)
                    tr.ml(lst[j],rst[j]);
            }else if(op[1]=='S')
            {
                int Lca = get_lca(x,y);
                ll ans = queryS(x,Lca);
                ans+=queryS(y,Lca);
                ans-=tr.get_kw(tin[Lca]);
                printf("%lld
    ",ans);
            }else if(op[1]=='M'&&op[2]=='a')
            {
                int Lca = get_lca(x,y);
                int ans = max(queryMax(x,Lca),queryMax(y,Lca));
                printf("%d
    ",ans);
            }else
            {
                int Lca = get_lca(x,y);
                int ans = min(queryMin(x,Lca),queryMin(y,Lca));
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HashTable, HashMap,TreeMap区别
    redis的多线程
    五种I/O模型介绍
    SpringBoot的优点
    spring注解
    三种方法求解两个数组的交集
    数据库七种传播行为
    BETA 版冲刺前准备
    Python学习笔记(二)--变量和数据类型
    事后诸葛亮
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10907010.html
Copyright © 2020-2023  润新知