zoukankan      html  css  js  c++  java
  • hdu 5052 Yaoge’s maximum profit

    Yaoge’s maximum profit

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 442    Accepted Submission(s): 122


    Problem Description
    Yaoge likes to eat chicken chops late at night. Yaoge has eaten too many chicken chops, so that Yaoge knows the pattern in the world of chicken chops. There are N cities in the world numbered from 1 to N . There are some roads between some cities, and there is one and only one simple path between each pair of cities, i.e. the cities are connected like a tree. When Yaoge moves along a path, Yaoge can choose one city to buy ONE chicken chop and sell it in a city after the city Yaoge buy it. So Yaoge can get profit if Yaoge sell the chicken chop with higher price. Yaoge is famous in the world. AFTER Yaoge has completed one travel, the price of the chicken chop in each city on that travel path will be increased by V .
     
    Input
    The first line contains an integer T (0 < T ≤ 10), the number of test cases you need to solve. For each test case, the first line contains an integer N (0 < N ≤ 50000), the number of cities. For each of the next N lines, the i-th line contains an integer Wi(0 < Wi ≤ 10000), the price of the chicken chop in city i. Each of the next N - 1 lines contains two integers X Y (1 ≤ X, Y ≤ N ), describing a road between city X and city Y . The next line contains an integer Q(0 ≤ Q ≤ 50000), the number of queries. Each of the next Q lines contains three integer X Y V(1 ≤ X, Y ≤ N ; 0 < V ≤ 10000), meaning that Yaoge moves along the path from city X to city Y , and the price of the chicken chop in each city on the path will be increased by V AFTER Yaoge has completed this travel.
     
    Output
    For each query, output the maximum profit Yaoge can get. If no positive profit can be earned, output 0 instead.
     
    Sample Input
    1 5 1 2 3 4 5 1 2 2 3 3 4 4 5 5 1 5 1 5 1 1 1 1 2 5 1 1 1 2 1
     
    Sample Output
    4 0 0 1 0
     
    Source

     思路:lct or 树链分割

    调了三天,终于过了,。。。不容易呀。。。

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<set>
    #include<stack>
    #include<map>
    #include<ctime>
    #include<bitset>
    #define LL long long
    #define INF 999999
    #define mod 20140518
    #define maxn 50010
    using namespace std;
    
    int head[maxn],next1[maxn*2],to[maxn*2] ;
    int top1 ;
    bool vi[maxn] ;
    struct node
    {
        int Max,Min;
        int add,lans,rans;
    }tree[maxn*3],num[maxn];
    int ql,qr,val ;
    node vv ;
    int max(int x,int y ){return x > y?x:y;}
    int min(int x,int y ){return x < y?x:y;}
    
    void Unit(int u,int v )
    {
        next1[top1] = head[u] ;to[top1] = v ;
        head[u] = top1++;
    }
    void up(int o )
    {
        tree[o].Max = max(tree[o<<1].Max,tree[o<<1|1].Max) ;
        tree[o].Min = min(tree[o<<1].Min,tree[o<<1|1].Min) ;
        tree[o].lans = max(tree[o<<1].lans,tree[o<<1|1].lans) ;
        tree[o].lans = max(tree[o].lans,tree[o<<1].Max-tree[o<<1|1].Min) ;
        tree[o].rans = max(tree[o<<1].rans,tree[o<<1|1].rans) ;
        tree[o].rans = max(tree[o].rans,tree[o<<1|1].Max-tree[o<<1].Min) ;
    }
    void Add(int o ,int add)
    {
        tree[o].add += add ;
        tree[o].Max += add ;
        tree[o].Min += add ;
    }
    void down(int o )
    {
        if(tree[o].add)
        {
           Add((o<<1),tree[o].add) ;
           Add((o<<1|1),tree[o].add) ;
           tree[o].add = 0;
        }
    }
    void insert(int L,int R,int o )
    {
        tree[o].add=0;
        if(L==R)
        {
            tree[o] = num[L] ;
            return ;
        }
        int mid=(L+R)>>1 ;
        insert(L,mid,o<<1) ;
        insert(mid+1,R,o<<1|1) ;
        up(o) ;
    }
    void update(int L,int R,int o )
    {
        if(ql <= L && qr >= R)
        {
            Add(o,val) ;
            return ;
        }
        down(o) ;
        int mid=(L+R)>>1 ;
        if(ql <= mid)update(L,mid,o<<1) ;
        if(qr > mid) update(mid+1,R,o<<1|1) ;
        up(o);
    }
    void find(int L,int R,int o,node &c )
    {
        if(ql <= L && qr >= R)
        {
            c = tree[o] ;
            return ;
        }
        int mid=(L+R)>>1 ;
        down(o) ;
        if(ql > mid)
        {
           find(mid+1,R,o<<1|1,c) ;
           return ;
        }
        else if(qr <= mid)
        {
            find(L,mid,o<<1,c) ;
            return ;
        }
        node a ;
        find(L,mid,o<<1,a) ;
        node b ;
        find(mid+1,R,o<<1|1,b) ;
        c.Max = max(a.Max,b.Max) ;
        c.Min = min(a.Min,b.Min) ;
        c.lans = max(a.lans,max(a.Max-b.Min,b.lans)) ;
        c.rans = max(a.rans,max(b.Max-a.Min,b.rans)) ;
    }
    int w[maxn],fa[maxn],top[maxn],sz ;
    int size1[maxn],son[maxn] ,dep[maxn];
    void init()
    {
        memset(w,0,sizeof(w));
        memset(size1,0,sizeof(size1)) ;
        memset(dep,0,sizeof(dep)) ;
        memset(son,0,sizeof(son)) ;
        memset(top,0,sizeof(top)) ;
        memset(fa,0,sizeof(fa)) ;
    }
    void dfs(int u)
    {
        size1[u] = 1 ;son[u] = 0 ;
        for(int i = head[u] ; i != -1 ; i = next1[i])
        {
            int v = to[i] ;
            if(v==fa[u]) continue ;
            fa[v]=u;
            dep[v] = dep[u]+1;
            dfs(v) ;
            if(size1[v] > size1[son[u]])
                son[u] = v ;
            size1[u] += size1[v] ;
        }
    }
    void build(int u,int t)
    {
        top[u] = t ;
        w[u] = ++sz ;
        if(son[u]) build(son[u],t) ;
        for(int i = head[u] ; i != -1 ; i = next1[i])
        {
            int v = to[i] ;
            if(v==fa[u]||v==son[u]) continue ;
            build(v,v) ;
        }
    }
    int query(int u,int v )
    {
        int f1,f2,flag=0,ans=0;
        node a[2],b,c,d;
        f1 = top[u] ;
        f2 = top[v] ;
        a[0].Max=a[1].Max=-1;
        while(f1 != f2)
        {
          //  puts("==========");
            if(dep[f1] < dep[f2])
            {
                swap(f1,f2) ;
                swap(u,v) ;
                flag ^= 1;
            }
            ql = w[f1] ;qr = w[u] ;
            u = fa[f1] ;f1=top[u] ;
            find(1,sz,1,d) ;
            if(a[flag].Max==-1)
            {
                a[flag] = d ;
                continue ;
            }
            b = d ;
            d = a[flag] ;
            c.Max = max(d.Max,b.Max) ;
            c.Min = min(d.Min,b.Min) ;
            c.lans = max(d.lans,max(b.Max-d.Min,b.lans)) ;
            c.rans = max(d.rans,max(d.Max-b.Min,b.rans)) ;
            if(flag) ans = max(ans,c.rans) ;
            else ans = max(ans,c.lans);
            a[flag] = c ;
        }
        if(dep[u] < dep[v])
        {
             swap(u,v) ;
             flag ^= 1;
        }
        ql = w[v] ; qr = w[u] ;
        find(1,sz,1,d)  ;
        if(a[flag].Max!=-1){
            b = d ;
            d = a[flag] ;
            c.Max = max(d.Max,b.Max) ;
            c.Min = min(d.Min,b.Min) ;
            c.lans = max(d.lans,max(b.Max-d.Min,b.lans)) ;
            c.rans = max(d.rans,max(d.Max-b.Min,b.rans)) ;
            if(flag) ans = max(ans,c.rans) ;
            else ans = max(ans,c.lans);
            a[flag] = c ;
        }
        else a[flag] = d ;
        if(a[0].Max==-1)
        {
            return max(ans,a[1].rans) ;
        }
        else if(a[1].Max==-1)
        {
           // puts("-----------");
          // // cout << a[0].lans << "==" << a[0].rans << endl;
            return max(ans,a[0].lans) ;
        }
        ans = max(ans,a[1].rans);
        ans = max(ans,a[0].lans);
        ans = max(ans,a[1].Max-a[0].Min);
        return ans;
    }
    void ADD(int u,int v ,int c )
    {
        int f1,f2;
        f1 = top[u];f2=top[v] ;
        val = c ;
        while(f1 != f2)
        {
            if(dep[f1] < dep[f2])
            {
                swap(f1,f2) ;
                swap(u,v) ;
            }
            ql=w[f1] ;qr=w[u] ;
            u = fa[f1] ;
            f1 = top[u] ;
            update(1,sz,1) ;
        }
        if(dep[u] >dep[v])
            swap(u,v) ;
        ql = w[u];qr=w[v] ;
        update(1,sz,1);
    }
    int next_int() {
        char c;
        int re = 0;
        c = getchar();
        while (c < '0' || c > '9') c = getchar();
        while (c >= '0' && c <= '9') {
            re = re*10+c-'0';
            c = getchar();
        }
        return re;
    }
    
    int ee[maxn] ;
    int main()
    {
        int n,m,x,y,i,j;
        int T,c ;
        //freopen("in.txt","r",stdin);
        scanf("%d",&T);
        while( T-- )
        {
            n = next_int();
            memset(head,-1,sizeof(head)) ;
            top1=0;
            for( i = 1 ; i <= n ;i++)
            {
               // scanf("%d",&ee[i]) ;
               ee[i]=next_int();
            }
            for( i = 1 ; i < n ;i++)
            {
               // scanf("%d%d",&x,&y) ;
                x = next_int();
                y = next_int();
                Unit(x,y) ;
                Unit(y,x) ;
            }
            sz=0;
            init();
            dfs(1) ;
            build(1,1);
            for( i = 1 ; i <= n ;i++)
            {
                ql=w[i];
                vv.Max = ee[i];
                vv.Min = ee[i] ;
                vv.lans = vv.rans = 0;
                num[ql] = vv ;
            }
            insert(1,sz,1);
            m = next_int();
            while(m--)
            {
               //  scanf("%d%d%d",&x,&y,&c) ;
                 x = next_int();
                 y = next_int();
                 c = next_int();
                 printf("%d
    ",query(x,y)) ;
                 ADD(x,y,c) ;
            }
        }
        return 0 ;
    }
    

      

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<set>
    #include<stack>
    #include<map>
    #include<ctime>
    #include<bitset>
    #define LL long long
    #define INF 999999
    #define mod 20140518
    #define maxn 100010
    using namespace std;
    
    int head[maxn],next1[maxn*2],to[maxn*2] ;
    int top ,n ;
    bool vi[maxn] ;
    
    void Unit(int u,int v )
    {
        next1[top] = head[u] ;to[top] = v ;
        head[u] = top++;
    }
    struct LCT
    {
        int w[maxn],add[maxn],Max[maxn];
        int ch[maxn][2],pre[maxn] ;
        int L[maxn] ;
        int Min[maxn],ans[maxn] ;
        bool rev[maxn] ;
        void init()
        {
            memset(rev,0,sizeof(rev)) ;
            memset(ch,0,sizeof(ch)) ;
            memset(add,0,sizeof(add));
            memset(pre,0,sizeof(pre)) ;
            memset(Max,0,sizeof(Max)) ;
            memset(ans,0,sizeof(ans)) ;
            memset(Min,0,sizeof(Min)) ;
            memset(L,0,sizeof(L)) ;
        }
        void Add(int x ,int val)
        {
            if(x)
            {
                add[x] += val ;
                w[x] += val ;
                Max[x] += val ;
                Min[x] += val ;
            }
        }
        void update(int x )
        {
            Max[x] = max(w[x],max(Max[ch[x][0]],Max[ch[x][1]])) ;
            Min[x] = w[x];
            if(ch[x][1]) Min[x] = min(Min[ch[x][1]],Min[x]) ;
            if(ch[x][0]) Min[x] = min(Min[ch[x][0]],Min[x]) ;
            ans[x] = max(ans[ch[x][0]],max(0,ans[ch[x][1]])) ;
            if(ch[x][0]&&ch[x][1])ans[x] = max(ans[x],Max[ch[x][0]]-Min[ch[x][1]]) ;
            if(ch[x][0])ans[x] = max(ans[x],Max[ch[x][0]]-w[x]) ;
            if(ch[x][1])ans[x] = max(ans[x],w[x]-Min[ch[x][1]]) ;
    
            L[x] = max(L[ch[x][0]],max(0,L[ch[x][1]])) ;
            if(ch[x][0]&&ch[x][1])L[x] = max(L[x],Max[ch[x][1]]-Min[ch[x][0]]) ;
            if(ch[x][1])L[x] = max(L[x],Max[ch[x][1]]-w[x]) ;
            if(ch[x][0])L[x] = max(L[x],w[x]-Min[ch[x][0]]) ;
        }
        void down(int x )
        {
            if(add[x])
            {
                Add(ch[x][0],add[x]) ;
                Add(ch[x][1],add[x]) ;
                add[x]=0;
            }
            return ;
            if(rev[x])
            {
                swap(ch[x][0],ch[x][1]) ;
                rev[ch[x][0]] ^= 1;
                rev[ch[x][1]] ^= 1;
                rev[x] = 0;
            }
        }
        bool isroot(int x )
        {
            if(ch[pre[x]][0] != x && ch[pre[x]][1] != x )
                return true ;
            return false;
        }
        void pushdown(int x )
        {
            if(!isroot(x)) pushdown(pre[x]) ;
            down(x) ;
        }
        void rotate(int x,int f)
        {
            int y = pre[x],z = pre[y];
            ch[y][!f] = ch[x][f];
            pre[ ch[x][f] ] = y;
            pre[x] = pre[y];
            if(ch[z][0] == y)ch[z][0] = x;
            else if(ch[z][1] == y)ch[z][1] = x;
            pre[y] = x;
            ch[x][f] = y;
            update(y);
        }
        void splay(int x)
        {
            pushdown(x);
            while(!isroot(x))
            {
                if(isroot(pre[x]))rotate(x,ch[pre[x]][0] == x);
                else
                {
                    int y = pre[x],z = pre[y];
                    int f = (ch[z][0] == y);
                    if(ch[y][f] == x)rotate(x,!f),rotate(x,f);
                    else rotate(y,f),rotate(x,f);
                }
            }
            update(x);
        }
        void access(int u)
        {
            for(int f = 0 ; u ;u = pre[u])
            {
                splay(u);
                ch[u][1] = f ;
                update(u);
                f = u ;
            }
        }
        bool check(int a ,int b)
        {
            int x =a,y=b;
            access(y) ;
            for(int f = 0 ;x ;x = pre[x])
            {
                splay(x) ;
                if(!pre[x]) break ;
                f = x ;
            }
            for( ; ch[x][1] ; x = ch[x][1]);
            return x == b ;
        }
        void make_root(int x )
        {
            access(x) ;
            splay(x) ;
            rev[x] ^= 1;
        }
        void cut(int x,int y )
        {
            if(x==y||!check(x,y))
            {
                puts("-1") ;
                return ;
            }
            make_root(x) ;
            splay(y) ;
            pre[ch[y][0]] = pre[y] ;
            pre[y] = ch[y][0] = 0 ;
        }
        int find(int x,int y )
        {
            access(y) ;
            for( int f = 0 ; x ; x = pre[x])
            {
                splay(x) ;
                if(!pre[x])
                {
                    int Max1 = 0 ;
                    Max1 = max(ans[f],L[ch[x][1]]);
                    if(ch[x][1])Max1 = max(Max1,Max[ch[x][1]]-w[x]) ;
                    if(f)Max1 = max(Max1,w[x]-Min[f]) ;
                    if(ch[x][1]&&f) Max1= max(Max1,Max[ch[x][1]]-Min[f]);
                    return Max1;
                }
                ch[x][1] = f ;
                f = x ;
                update(x) ;
            }
            return -1;
        }
        void add1(int x ,int y ,int add)
        {
            access(y) ;
            for(int f = 0 ; x ; x = pre[x])
            {
                splay(x) ;
                if(!pre[x])
                {
                    w[x] += add ;
                    Max[x] += add ;
                    Min[x] += add ;
                    Add(f,add) ;
                    Add(ch[x][1],add) ;
                    return ;
                }
                ch[x][1] = f ;
                f = x ;
                update(x) ;
            }
        }
        void link(int x,int y )
        {
            make_root(x) ;
            pre[x]=y;
        }
    }lct;
    void dfs(int u,int f)
    {
        for(int i = head[u]; i != -1; i=next1[i])
        {
            int v = to[i] ;
            if(v==f) continue ;
            dfs(v,u);
            lct.pre[v] = u;
        }
    }
    int next_int() {
        char ch;
        int res;
        bool neg;
        while (ch = getchar(), !isdigit(ch) && ch != '-')
            ;
        if (ch == '-') {
            neg = true;
            res = 0;
        } else {
            neg = false;
            res = ch - '0';
        }
        while (ch = getchar(), isdigit(ch))
            res = res * 10 + ch - '0';
        return neg ? -res : res;
    }
    int main()
    {
        int n,m,i,j,k;
        int T,case1=0,u,v,c ;
       // freopen("in.txt","r",stdin);
        cin >> T ;
        while(T--)
        {
            scanf("%d",&n) ;
            lct.init();
            for( i = 1 ; i <= n ;i++)
            {
                lct.w[i] = next_int() ;
            //    lct.Max[i] = lct.Min[i] = lct.w[i];
            }
            top=0;
            memset(head,-1,sizeof(head)) ;
            for( i = 1 ; i < n ;i++)
            {
                u = next_int();
                v = next_int();
                Unit(u,v) ;
                Unit(v,u) ;
            }
            dfs(1,-1);
            scanf("%d",&m) ;
            while(m--)
            {
                //scanf("%d%d%d",&u,&v,&c) ;
                u = next_int();
                v = next_int();
                c = next_int();
                printf("%d
    ",lct.find(u,v)) ;
                lct.add1(u,v,c) ;
            }
        }
        return 0 ;
    }
    

      

  • 相关阅读:
    多测师讲解jmeter _ 导入本地文本内容参数化方法一__(1)高级讲师肖sir
    深圳_多测师面试 _平安项目总结(2020年10月)_高级讲师肖sir
    多测师讲解jmeter _token提取_高级讲师肖sir
    多测师讲解jmeter _图片详解_(全)高级讲师肖sir
    深圳精英面试总结——华为外包面试,明源云客,有咖面试,招商面试 总结(001)
    多测师讲解接口测试 —jmeter接数据库(004)_高级讲师肖sir
    多测师讲解jmeter _接口请求_(003)高级讲师肖sir
    多测师讲解jmeter _安装和配置环境(00)_高级讲师肖sir
    多测师讲解接口 _需求文档(用户增删改查)_高级讲师肖sir
    jemeter参数化读取文件
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/4005688.html
Copyright © 2011-2022 走看看