zoukankan      html  css  js  c++  java
  • bzoj1036

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 14796  Solved: 5991
    [Submit][Status][Discuss]

    Description

      一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
    一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
    II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

    Input

      输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
    一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
    的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
    对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

    Output

      对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

    Sample Input

    4
    1 2
    2 3
    4 1
    4 2 1 3
    12
    QMAX 3 4
    QMAX 3 3
    QMAX 3 2
    QMAX 2 3
    QSUM 3 4
    QSUM 2 1
    CHANGE 1 5
    QMAX 3 4
    CHANGE 3 6
    QMAX 3 4
    QMAX 2 4
    QSUM 3 4

    Sample Output

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16

    HINT

    Source

    lct练习题。错误:一定要先把初始点权算好再连边。。。这也是错误

    晚上不能松懈啊,要有明确的的计划!

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define N 300010
    int n,q;
    int fa[N],tag[N],st[N],key[N],u[N],v[N];
    ll mx[N],sum[N];
    int child[N][2];
    ll max(ll x,ll y)
    {
        return x>y?x:y;
    }
    void update(int x)
    {
        sum[x]=sum[child[x][0]]+sum[child[x][1]]+key[x];
        mx[x]=max(key[x],max(mx[child[x][0]],mx[child[x][1]]));
    }
    bool isroot(int x)
    {
        return (!fa[x]||(child[fa[x]][0]!=x&&child[fa[x]][1]!=x));
    }
    void pushdown(int x)
    {
        if(!tag[x]) return;
        tag[x]^=1;
        swap(child[x][0],child[x][1]);
        tag[child[x][0]]^=1;
        tag[child[x][1]]^=1;
    }
    void zig(int x)
    {
        int y=fa[x];
        fa[x]=fa[y];
        if(!isroot(y)) child[fa[x]][child[fa[x]][1]==y]=x;
        child[y][0]=child[x][1]; fa[child[x][1]]=y;
        fa[y]=x; child[x][1]=y;
        update(y); update(x);
    }
    void zag(int x)
    {
        int y=fa[x];
        fa[x]=fa[y];
        if(!isroot(y)) child[fa[x]][child[fa[x]][1]==y]=x;
        child[y][1]=child[x][0]; fa[child[x][0]]=y;
        fa[y]=x; child[x][0]=y;
        update(y); update(x);
    }
    void splay(int x)
    {
        int top=0; st[++top]=x;
        for(int y=x;!isroot(y);y=fa[y]) st[++top]=fa[y];
        for(int i=top;i;i--) pushdown(st[i]);
        while(!isroot(x))
        {
            int y=fa[x],z=fa[y];
            if(isroot(y))
            {
                child[y][0]==x?zig(x):zag(x); break;
            }
            child[y][0]==x?zig(x):zag(x);
            child[z][0]==x?zig(x):zag(x);
        }
    }
    void access(int x)
    {
        for(int t=0;x;t=x,x=fa[x])
        {
            splay(x);
            child[x][1]=t;
            update(x);
        }
    }
    void rever(int x)
    {
        access(x); splay(x); tag[x]^=1;
    }
    void link(int u,int v)
    {
        rever(u); fa[u]=v;
    }
    void change(int u,int v)
    {
        key[u]=v; update(u); splay(u); 
    }
    void querymax(int u,int v)
    {
        rever(u); access(v); splay(v);
        printf("%lld
    ",mx[v]);
    }
    void querysum(int u,int v)
    {
        rever(u); access(v); splay(v);
        printf("%lld
    ",sum[v]);
    }
    int main()
    {
        memset(mx,-0x3f3f,sizeof(mx));
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u[i],&v[i]);
        }
        for(int i=1;i<=n;i++) 
        {
            scanf("%d",&key[i]);
            update(i);
        }
        for(int i=1;i<n;i++) link(u[i],v[i]);
        scanf("%d",&q);
        while(q--)
        {
            char s[10]; scanf("%s",s);
            if(s[1]=='M')
            {
                int u,v; scanf("%d%d",&u,&v);
                querymax(u,v);
            }
            if(s[1]=='S')
            {
                int u,v; scanf("%d%d",&u,&v);
                querysum(u,v);
            }
            if(s[1]=='H')
            {
                int u,v; scanf("%d%d",&u,&v);
                change(u,v);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Qt passwd echoMode placeholer QString.trimmed()
    bit opt
    Linux Kernel Development系统调用
    Linux Kernel Development——列出系统中所有的进程
    Linux Kernel Development——内存管理
    Linux Kernel Development——定时器和时间管理
    Linux Kernel Development——内核同步方法
    [转]Linux 2.6中断下半部机制分析
    Linux Kernel Development——中断
    Linux Kernel Development——虚拟文件系统
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6291439.html
Copyright © 2011-2022 走看看