• bzoj1036:[ZJOI2008]树的统计Count


    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
     
    题解:
    树链剖分模板~
    第一次自己写,终于写过了
    修改对应到线段树中的单点修改,查询就是不断向上跳top直到两个点在同一条链上,最后再”跳“一次把两个点跳到一起,过程中通过线段树求和与最大值
     
    注意:1.题目中说n<=30000,但实际不是这样,会RE!!!n的范围需要调大一些
    2.结点值可能为负!求路径上MAX时最先赋值应为-INF
    3.建双向边时数组大小要开2*MAXN
     
    代码:
      1 #include<iostream>
      2 #include<cstdio>
      3 #define INF 2147483647
      4 using namespace std;
      5 
      6 const int MAXN=1000005;
      7 struct node
      8 {
      9     int v;
     10     node *next;       
     11 }pool[MAXN],*h[MAXN];
     12 int cnt,tot;
     13 int val[MAXN],fa[MAXN],size[MAXN],son[MAXN],dep[MAXN],top[MAXN],w[MAXN],rank[MAXN];
     14 
     15 void addedge(int u,int v)
     16 {
     17     node *p=&pool[++cnt],*q=&pool[++cnt];
     18     p->v=v;p->next=h[u];h[u]=p;
     19     q->v=u;q->next=h[v];h[v]=q;
     20 }
     21 void dfs1(int u) //GET fa[],size[],dep[],son[]
     22 {
     23     int v;
     24     size[u]=1;
     25     int Bson=0,sonnum=0;
     26     for(node *p=h[u];p;p=p->next)
     27         if(fa[u]!=(v=p->v))
     28         {
     29             fa[v]=u;
     30             dep[v]=dep[u]+1;
     31             dfs1(v);
     32             size[u]+=size[v];
     33             if(size[v]>Bson) Bson=size[v],sonnum=v;                 
     34         }
     35     son[u]=sonnum;
     36 }
     37 void dfs2(int u) //GET top[],w[],rank[]
     38 {
     39     int v=son[u];
     40     if(v)
     41     {
     42         top[v]=top[u];
     43         rank[v]=++tot;
     44         w[rank[v]]=val[v];
     45         dfs2(v);
     46     }
     47     for(node *p=h[u];p;p=p->next)
     48         if(fa[v=p->v]==u && v!=son[u])
     49         {
     50             top[v]=v;
     51             rank[v]=++tot;
     52             w[rank[v]]=val[v];
     53             dfs2(v);                 
     54         }
     55 }
     56 
     57 struct tree
     58 {
     59     int l,r,sum,Max;
     60     tree *left,*right;       
     61 }t[3*MAXN],*root;
     62 int cnt1;
     63 void Build_Tree(tree *p,int l,int r)
     64 {
     65     p->l=l;p->r=r;
     66     if(l==r)
     67     {
     68         p->sum=p->Max=w[l];
     69         return;
     70     }
     71     tree *left=&t[++cnt1],*right=&t[++cnt1];
     72     p->left=left;p->right=right;
     73     int mid=(l+r)/2;
     74     Build_Tree(p->left,l,mid);
     75     Build_Tree(p->right,mid+1,r);
     76     p->sum=p->left->sum+p->right->sum;
     77     p->Max=max(p->left->Max,p->right->Max);
     78 }
     79 void change(tree *p,int l,int r,int c)
     80 {
     81     if(p->l==l && p->r==r)
     82     {
     83         p->sum=p->Max=c;
     84         return;           
     85     }
     86     if(p->left->r>=r) change(p->left,l,r,c);
     87     else if(p->right->l<=l) change(p->right,l,r,c);
     88     p->sum=p->left->sum+p->right->sum;
     89     p->Max=max(p->left->Max,p->right->Max);
     90 }
     91 int query_Max(tree *p,int l,int r)
     92 {
     93     if(p->l==l && p->r==r)
     94         return p->Max;
     95     if(p->left->r>=r) return query_Max(p->left,l,r);
     96     else if(p->right->l<=l) return query_Max(p->right,l,r);
     97     else return max(query_Max(p->left,l,p->left->r),query_Max(p->right,p->right->l,r));
     98 }
     99 int query_Sum(tree *p,int l,int r)
    100 {
    101     if(p->l==l && p->r==r)
    102         return p->sum;
    103     if(p->left->r>=r) return query_Sum(p->left,l,r);
    104     else if(p->right->l<=l) return query_Sum(p->right,l,r);
    105     else return query_Sum(p->left,l,p->left->r)+query_Sum(p->right,p->right->l,r);
    106 }
    107 
    108 int Max(int x,int y)
    109 {
    110     int ret=-INF;
    111     int f1=top[x],f2=top[y];
    112     while(f1!=f2)
    113     {
    114         if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
    115         ret=max(ret,query_Max(root,rank[f1],rank[x]));
    116         x=fa[top[x]];f1=top[x];       
    117     }
    118     if(dep[x]<dep[y]) swap(x,y);
    119     return max(ret,query_Max(root,rank[y],rank[x]));
    120 }
    121 int Sum(int x,int y)
    122 {
    123     int ret=0;
    124     int f1=top[x],f2=top[y];
    125     while(f1!=f2)
    126     {
    127         if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
    128         ret+=query_Sum(root,rank[f1],rank[x]);
    129         x=fa[top[x]];f1=top[x];      
    130     }
    131     if(dep[x]<dep[y]) swap(x,y);
    132     return ret+query_Sum(root,rank[y],rank[x]);
    133 }
    134 
    135 int main()
    136 {
    137     int n,q,i,a,b;
    138     char ch[10];
    139     scanf("%d",&n);
    140     for(i=1;i<n;i++)
    141         scanf("%d%d",&a,&b),addedge(a,b);
    142     for(i=1;i<=n;i++) scanf("%d",&val[i]);
    143     
    144     dfs1(1);
    145     rank[1]=1;tot=1;top[1]=1;w[1]=val[1];
    146     dfs2(1);
    147     root=&t[++cnt1];
    148     Build_Tree(root,1,n);
    149     
    150     scanf("%d",&q);
    151     while(q --> 0)
    152     {
    153         scanf("%s",ch);scanf("%d%d",&a,&b);
    154         if(ch[1]=='H')
    155             change(root,rank[a],rank[a],b);
    156         else if(ch[1]=='M')
    157             printf("%d
    ",Max(a,b));
    158         else printf("%d
    ",Sum(a,b));
    159     }
    160     
    161     return 0;
    162 }
    View Code
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    jquery animate() stop() finish() 方法使用
    ant 相关命令
    ant 安装 网址
    邮件
    webdriver until
    python HTML报告
    登录
    yun
    centos7搭建smb服务
    爬取图片
  • 原文地址:https://www.cnblogs.com/lindalee/p/7209984.html
Copyright © 2020-2023  润新知