• TJOI2015 旅游


    Description

     

    Input

    Output

     

    Sample Input

    输入:
    3
    1 2 3
    1 2
    2 3
    2
    1 2 100
    1 3 100

    Sample Output

    输出:
    1
    1
     

    Data Constraint

     

    解法:显然的链剖。维护区间max,min,前面减后面的max,后面减前面的max即可

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    
    struct Tree{
        int lr,rl,mx,mn,bz;
    }tr[400011];
    
    Tree Tm[111];
    int g[50011],next[100011],y[100011],num[50011],dep[50011],fa[50011],top[50011];
    int id[50011],son[50011],size[50011],pm[111],sm[111],val[50011];
    int tot,tt,n,i,x,z,q,ans,m;
    
    struct AA{
        int l,r,k,sh;
    }que[111];
    
    void star(int i,int j)
    {
        tt++;
        next[tt]=g[i];
        g[i]=tt;
        y[tt]=j;
    }
    
    void build_chain(int root)
    {
        int x;
        x=root;
        while(x){
            tot++;
            id[tot]=x;
            num[x]=tot;
            top[x]=root;
            x=son[x];
        }
    }
    
    void dfs(int x)
    {
        int j,k;
        size[x]=1;
        j=g[x];
        while(j!=0){
            k=y[j];
            if(k!=fa[x]){
                fa[k]=x;
                dep[k]=dep[x]+1;
                dfs(k);
                size[x]+=size[k];
                if(size[k]>size[son[x]]){
                    if(son[x])build_chain(son[x]);
                    son[x]=k;
                }
                else build_chain(k);
            }
            j=next[j];
        }
        
    }
    
    Tree Merge(Tree a,Tree b)
    {
        Tree c;
        c.mx=max(a.mx,b.mx);
        c.mn=min(a.mn,b.mn);
        c.rl=max(a.rl,b.rl);
        c.rl=max(c.rl,b.mx-a.mn);
        c.lr=max(a.lr,b.lr);
        c.lr=max(c.lr,a.mx-b.mn);
        return c;
    }
    
    void up(int t)
    {
        Tree a,b;
        Tree &c=tr[t];
        a=tr[t+t];b=tr[t+t+1];
        c.mx=max(a.mx,b.mx);
        c.mn=min(a.mn,b.mn);
        c.rl=max(a.rl,b.rl);
        c.rl=max(c.rl,b.mx-a.mn);
        c.lr=max(a.lr,b.lr);
        c.lr=max(c.lr,a.mx-b.mn);
    
    }
    
    void build(int l,int r,int t)
    {
        if(l==r){
            tr[t].mx=tr[t].mn=val[id[l]];
            tr[t].lr=tr[t].rl=0;
            tr[t].bz=0;
            return;
        }
        int mid;
        mid=(l+r)/2;
        build(l,mid,t+t);
        build(mid+1,r,t+t+1);
        tr[t].bz=0;
        up(t);
    }
    
    void change(int t,int x)
    {
        tr[t].bz+=x;
        tr[t].mx+=x;
        tr[t].mn+=x;
    }
    
    void down(int t,int l,int r)
    {
        if(l==r)return;
        if(tr[t].bz){
            change(t+t,tr[t].bz);
            change(t+t+1,tr[t].bz);
            tr[t].bz=0;
        }
    }
    
    void insert(int t,int l,int r,int x,int y,int z)
    {
        down(t,l,r);
        if(l==x&&r==y){
            change(t,z);
            return;
        }
        int mid;
        mid=(l+r)/2;
        if(y<=mid)insert(t+t,l,mid,x,y,z);
        if(x>mid)insert(t+t+1,mid+1,r,x,y,z);
        if(x<=mid&&y>mid){
            insert(t+t,l,mid,x,mid,z);
            insert(t+t+1,mid+1,r,mid+1,y,z);
        }
        up(t);
    }
    
    Tree ask(int t,int l,int r,int x,int y)
    {
        down(t,l,r);
        if(l==x&&r==y)return tr[t];
        Tree re;
        int mid;
        mid=(l+r)/2;
        if(y<=mid)re=ask(t+t,l,mid,x,y);
        if(x>mid)re=ask(t+t+1,mid+1,r,x,y);
        if(x<=mid&&y>mid)re=Merge(ask(t+t,l,mid,x,mid),ask(t+t+1,mid+1,r,mid+1,y));
        up(t);
        return re;
    }
    
    bool cmp(AA a,AA b)
    {
        if(a.k==b.k){
            if(a.k==1)return a.sh<b.sh;
            else return a.sh>b.sh;
        }
        else return a.k<b.k;
    }
    
    void Work(int st,int ed,int ad)
    {
        int bs,be,mn[3],i,ts(0);
        bs=1;be=2;
        mn[1]=mn[2]=0;
        while(true){
            if(top[st]==top[ed]){
                if(dep[st]<dep[ed])swap(st,ed),swap(bs,be);
                ts++;
                que[ts].l=num[ed];
                que[ts].r=num[st];
                que[ts].k=bs;
                que[ts].sh=++mn[bs];
                break;
            }
            else{
                if(dep[top[st]]<dep[top[ed]])swap(st,ed),swap(bs,be);
                ts++;
                que[ts].l=num[top[st]];
                que[ts].r=num[st];
                que[ts].k=bs;
                que[ts].sh=++mn[bs];
                st=fa[top[st]];
            }
        }
        sort(que+1,que+1+ts,cmp);
        for(i=1;i<=ts;i++)insert(1,1,n,que[i].l,que[i].r,ad);
        pm[0]=214748364;
        sm[ts+1]=-214748364;
        for(i=1;i<=ts;i++)Tm[i]=ask(1,1,n,que[i].l,que[i].r);
        for(i=1;i<=ts;i++)pm[i]=min(pm[i-1],Tm[i].mn);
        for(i=ts;i>=1;i--)sm[i]=max(sm[i+1],Tm[i].mx);
        ans=-214748364;
        for(i=1;i<=ts;i++){
            if(que[i].k==2)ans=max(ans,Tm[i].rl);
            else ans=max(ans,Tm[i].lr);
            ans=max(ans,sm[i+1]-pm[i]);
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)scanf("%d",&val[i]);
        for(i=1;i<n;i++){
            scanf("%d%d",&x,&z);
            star(x,z);
            star(z,x);
        }
        scanf("%d",&m);
        dfs(1);
        build_chain(1);
        build(1,n,1);
        for(i=1;i<=m;i++){
            scanf("%d%d%d",&x,&z,&q);
            Work(x,z,q);
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    把git项目放到个人服务器上
    关于fcitx无法切换输入法的问题解决
    博客变迁通知
    (欧拉回路 并查集 别犯傻逼的错了) 7:欧拉回路 OpenJudge 数据结构与算法MOOC / 第七章 图 练习题(Excercise for chapter7 graphs)
    (并查集) HDU 1856 More is better
    (并查集 不太会) HDU 1272 小希的迷宫
    (并查集 注意别再犯傻逼的错了) HDU 1213 How Many Tables
    (最小生成树 Kruskal算法) 51nod 1212 无向图最小生成树
    (并查集) HDU 1232 畅通工程
    (最小生成树 Prim) HDU 1233 还是畅通工程
  • 原文地址:https://www.cnblogs.com/applejxt/p/4475524.html
Copyright © 2020-2023  润新知