• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
mhy12345
博客园    首页    新随笔    联系   管理    订阅  订阅

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\n",&m);
        for (i=0;i<m;i++)
        {
                scanf("%s %d %d\n",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"\n",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 "\n",ans);
                }else
                {
                        val[pos[x]]=y;
                        Chg_val(1,pos[x]);
                }
        }
        return 0;
}

 

 
by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

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

posted @ 2014-10-14 09:32  mhy12345  阅读(175)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3