• BZOJ[1036] [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
     
    树链剖分模板题
     
     
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 using namespace std;
      8 int son[30001],fa[30001],v[30001],deep[30001],num[30001];
      9 int d[30001],t[30001],fd[30001];
     10 int s;
     11 struct data
     12 {
     13     int to,next;
     14 }a[60001];
     15 int head[30001];
     16 int cnt=0;
     17 void add(int u,int v){a[cnt].to=v;a[cnt].next=head[u];head[u]=cnt;cnt++;}
     18 int n;
     19 void dfs(int now,int f,int de)
     20 {
     21     fa[now]=f;
     22     deep[now]=de;
     23     num[now]=1;
     24     for(int i=head[now];i>=0;i=a[i].next)
     25     {
     26         if(a[i].to!=f)
     27         {
     28             dfs(a[i].to,now,de+1);
     29             num[now]+=num[a[i].to];
     30             if(num[a[i].to]>num[son[now]]) son[now]=a[i].to;
     31         }
     32     }
     33 }
     34 void dfs1(int now,int f,int tp)
     35 {
     36     t[now]=tp;
     37     d[now]=++s;
     38     fd[s]=now;
     39     if(son[now]) dfs1(son[now],now,tp);
     40     for(int i=head[now];i>=0;i=a[i].next)
     41     {
     42         int v=a[i].to;
     43         if(v!=son[now]&&v!=f) dfs1(v,now,v);
     44     }    
     45 }
     46 int maxn[90005],sum[90005];
     47 void pushup(int l,int r,int o)
     48 {
     49     int lo=o<<1,ro=lo+1;
     50     maxn[o]=max(maxn[lo],maxn[ro]);
     51     sum[o]=sum[lo]+sum[ro];
     52 }
     53 void build(int l,int r,int o)
     54 {
     55     if(l==r)maxn[o]=sum[o]=v[fd[l]];
     56     else
     57     {
     58         int mid=(l+r)>>1,lo=o<<1,ro=lo+1;
     59         build(l,mid,lo);
     60         build(mid+1,r,ro);
     61         pushup(l,r,o);
     62     }
     63 }
     64 
     65 void updata(int l,int r,int o,int m,int va)
     66 {
     67     if(l==m&&r==m) maxn[o]=sum[o]=va;
     68     else
     69     {
     70         int mid=(l+r)>>1,lo=o<<1,ro=lo+1;
     71         if(m>mid) updata(mid+1,r,ro,m,va);
     72         else updata(l,mid,lo,m,va);
     73         pushup(l,r,o);
     74     }
     75 }
     76 int al,ar,Max=-2147483647,Sum=0;
     77 void query(int l,int r,int o)
     78 {
     79     if(l>=al&&r<=ar)
     80     {
     81         Max=max(Max,maxn[o]);
     82         Sum+=sum[o];
     83     }
     84     else
     85     {
     86         int mid=(l+r)>>1,lo=o<<1,ro=lo+1;
     87         if(ar>mid) query(mid+1,r,ro);
     88         if(al<=mid) query(l,mid,lo);
     89     }
     90 }
     91 char ch[20];
     92 void find(int x,int y)
     93 {
     94     Max=-2147483647,Sum=0;
     95     int f1=t[x],f2=t[y];
     96     while(f1!=f2)
     97     {
     98         if(deep[f1]<deep[f2])
     99         {
    100             swap(f1,f2);
    101             swap(x,y);
    102         }
    103         al=d[f1],ar=d[x];
    104         query(1,n,1);
    105         x=fa[f1];
    106         f1=t[x];
    107     }
    108     if(deep[x]>deep[y]) swap(x,y);
    109     al=d[x],ar=d[y];
    110     query(1,n,1);
    111     if(ch[1]=='M') printf("%d
    ",Max);
    112     else printf("%d
    ",Sum);
    113 }
    114 int main()
    115 {
    116     memset(head,-1,sizeof(head));
    117     scanf("%d",&n);
    118     for(int i=1;i<n;i++)
    119     {
    120         int u1,v1;
    121         scanf("%d%d",&u1,&v1);
    122         add(u1,v1);
    123         add(v1,u1);
    124     }
    125     for(int i=1;i<=n;i++) scanf("%d",&v[i]);
    126     dfs(1,0,1);
    127     dfs1(1,0,1);
    128     build(1,n,1);
    129     int q;
    130     scanf("%d",&q);
    131     for(int i=1;i<=q;i++)
    132     {
    133         
    134         scanf("%s",ch);
    135         int x,y;
    136         if(ch[0]=='C')
    137         {
    138             scanf("%d%d",&x,&y);
    139             updata(1,n,1,d[x],y);
    140         }
    141         else
    142         {
    143             scanf("%d%d",&x,&y);
    144             find(x,y);
    145         }
    146     }
    147     //system("pause");
    148 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    Machine Learning Methods: Decision trees and forests
    The mean shift clustering algorithm
    Google Protocol Buffer 的使用和原理
    VS2013配置Caffe卷积神经网络工具(64位Windows 7)——准备依赖库
    测天之梯——2010年爱因斯坦讲座公众数学演讲《宇宙距离之梯》
    概率论复习 – 基础概率分布
    Conjugate prior relationships
    PRML Chapter 2. Probability Distributions
    PRML Chapter 1. Introduction
    POJ 2115 C Looooops(扩展欧几里得应用)
  • 原文地址:https://www.cnblogs.com/wls001/p/7168736.html
Copyright © 2020-2023  润新知