zoukankan      html  css  js  c++  java
  • bzoj 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 5442  Solved: 2285
    [Submit][Status]

    Description

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. 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

      这道题主要是试验了一下用bfs写链剖,以前居然不知道将bfs的队列改为栈就可以搞出dfs序。。。。。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    #define MAXN 31000
    #define MAXT 121000
    #define MAXV MAXN*2
    #define MAXE MAXV*2
    #define INF 0x3f3f3f3f
    #define INFL 0x3f3f3f3f3f3f3f3fLL
    #define lch (now<<1)
    #define rch (now<<1^1)
    typedef long long qword;
    inline int nextInt()
    {
            char ch;
            int x=0;
            bool flag=false;
            do
                    ch=(char)getchar(),flag=(ch=='-')?true:flag;
            while(ch<'0'||ch>'9');
            do x=x*10+ch-'0';
            while (ch=(char)getchar(),ch<='9' && ch>='0');
            return x*(flag?-1:1);
    }
    struct sgt_t
    {
            int l,r;
            qword mx,sum;
    }sgt[MAXT];
    int val[MAXT];
    void Build_tree(int now,int l,int r)
    {
            sgt[now].l=l;
            sgt[now].r=r;
            if (l==r)
            {
                    sgt[now].mx=sgt[now].sum=val[l];
                    return ;
            }
            Build_tree(lch,l,(l+r)>>1);
            Build_tree(rch,((l+r)>>1)+1,r);
            sgt[now].mx=max(sgt[lch].mx,sgt[rch].mx);
            sgt[now].sum=sgt[lch].sum+sgt[rch].sum;
    }
    void Chg_val(int now,int pos)
    {
            if (sgt[now].l == sgt[now].r)
            {
                    sgt[now].mx=sgt[now].sum=val[pos];
                    return ;
            }
            if (pos<=(sgt[now].l+sgt[now].r>>1))
                    Chg_val(lch,pos);
            else
                    Chg_val(rch,pos);
            sgt[now].mx=max(sgt[lch].mx,sgt[rch].mx);
            sgt[now].sum=sgt[lch].sum+sgt[rch].sum;
    }
    qword Qry_sum(int now,int l,int r)
    {
            if (sgt[now].l == l && sgt[now].r == r)
            {
                    return sgt[now].sum;
            }
            int mid=(sgt[now].l+sgt[now].r)>>1;
            if (r<=mid)
                    return Qry_sum(lch,l,r);
            if (mid<l)
                    return Qry_sum(rch,l,r);
            return Qry_sum(lch,l,mid)+Qry_sum(rch,mid+1,r);
    }
    qword Qry_max(int now,int l,int r)
    {
            if (sgt[now].l == l && sgt[now].r == r)
            {
                    return sgt[now].mx;
            }
            int mid=(sgt[now].l+sgt[now].r)>>1;
            if (r<=mid)
                    return Qry_max(lch,l,r);
            if (mid<l)
                    return Qry_max(rch,l,r);
            return max(Qry_max(lch,l,mid),Qry_max(rch,mid+1,r));
    }
    int n,m;
    struct Edge
    {
            int np;
            Edge *next;
    }E[MAXE],*V[MAXV];
    int tope=-1;
    void addedge(int x,int y)
    {
            E[++tope].np=y;
            E[tope].next=V[x];
            V[x]=&E[tope];
    }
    int stack[MAXN];
    int tops=-1;
    int seq[MAXN];
    int pos[MAXN];
    int fa[MAXN];
    int siz[MAXN],son[MAXN],depth[MAXN];
    int top[MAXN];
    void bfs(int x)
    {
            int now;
            int bst;
            int i;
            int idx;
            Edge *ne;
            stack[0]=x;
            tops=0;
            idx=-1;
            while (~tops)
            {
                    now=stack[tops--];
                    seq[++idx]=now;
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->np==fa[now])continue;
                            depth[ne->np]=depth[now]+1;
                            fa[ne->np]=now;
                            stack[++tops]=ne->np;
                    }
            }
            for (i=n-1;i>=0;i--)
            {
                    now=seq[i];
                    siz[now]=1;
                    bst=0;
                    son[now]=-1;
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->np==fa[now])continue;
                            siz[now]+=siz[ne->np];
                            if (siz[ne->np]>bst)
                            {
                                    son[now]=ne->np;
                                    bst=siz[ne->np];
                            }
                    }
            }
            stack[0]=x;
            top[x]=x;
            tops=0;
            idx=0;
            while (~tops)
            {
                    now=stack[tops--];
                    seq[++idx]=now;
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->np==fa[now] || ne->np==son[now])continue;
                            top[ne->np]=ne->np;
                            stack[++tops]=ne->np;
                    }
                    if (~son[now])
                    {
                            stack[++tops]=son[now];
                            top[son[now]]=top[now];
                    }
            }
            for (i=1;i<=n;i++)
            {
                    pos[seq[i]]=i;
            }
    }
    int main()
    {
            //freopen("input.txt","r",stdin);
            //freopen("output.txt","w",stdout);
            int i,j,k;
            int x,y,z;
            scanf("%d",&n);
            for (i=1;i<n;i++)
            {
                    scanf("%d%d",&x,&y);
                    addedge(x,y);
                    addedge(y,x);
            }
            bfs(1);
            for (i=1;i<=n;i++)
            {
                    scanf("%d",&x);
                    val[pos[i]]=x;
            }
            Build_tree(1,1,n);
            char opt[10];
            qword ans=0;
            scanf("%d
    ",&m);
            for (i=0;i<m;i++)
            {
                    scanf("%s %d %d
    ",opt,&x,&y);
                    if (opt[1]=='M')
                    {
                            ans=-INF;
                            while (true)
                            {
                                    if (top[x]==top[y])
                                    {
                                            if (depth[x]>depth[y])swap(x,y);
                                            ans=max(ans,Qry_max(1,pos[x],pos[y]));
                                            y=x;
                                            break;
                                    }
                                    if (depth[top[x]]<depth[top[y]])swap(x,y);
                                    ans=max(ans,Qry_max(1,pos[top[x]],pos[x]));
                                    x=fa[top[x]];
                            }
                            printf(LL"
    ",ans);
                    }else if (opt[1]=='S')
                    {
                            ans=0;
                            while (true)
                            {
                                    if (top[x]==top[y])
                                    {
                                            if (depth[x]>depth[y])swap(x,y);
                                            ans+=Qry_sum(1,pos[x],pos[y]);
                                            break;
                                    }
                                    if (depth[top[x]]<depth[top[y]])swap(x,y);
                                    ans+=Qry_sum(1,pos[top[x]],pos[x]);
                                    x=fa[top[x]];
                            }
                            printf(LL "
    ",ans);
                    }else
                    {
                            val[pos[x]]=y;
                            Chg_val(1,pos[x]);
                    }
            }
            return 0;
    }
     
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    多层装饰器执行顺序
    flask之 中间件 蓝图 falsk请求上下文 rquirements.txt threading.local 偏函数
    flask 之 在flask中使用websocket
    flask 之项目分文件使用sqlalchemy+flask-migrate djagno多数据库
    flask之六 sqlachemy详解 scoped_session线程安全 基本增删改查 多对多关系建立和操作 flask-sqlalchemy的使用
    远程连接linux开发项目
    INT104-lab9
    INT104-lab8
    INT104-lab7
    Java-数据结构-泛型BST-CPT102-tutorial Week6
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4023692.html
Copyright © 2011-2022 走看看