zoukankan      html  css  js  c++  java
  • 【ZJOI2008】 树的统计 count

    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

    思路

        又是从浙江挂下来的考数据结构的歪风邪气。

      树链剖分。不过我们不以边为元素,而以点为元素。由于一个点有可能被访问两次,所以在判重方面有一些麻烦。

         大体的思想是每次把点向上提的时候处理提到的节点,但不处理当前的节点。。

         恩。。这份代码应该是写的比较差吧,就当复习树链剖分了。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <string>
      4 #include <cstdio>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <algorithm>
      8 #include <queue>
      9 #include <stack>
     10 #include <map>
     11 #include <set>
     12 #include <list>
     13 #include <vector>
     14 #include <ctime>
     15 #include <functional>
     16 #define pritnf printf
     17 #define scafn scanf
     18 #define sacnf scanf
     19 #define For(i,j,k) for(int i=(j);i<=(k);(i)++)
     20 #define Clear(a) memset(a,0,sizeof(a))
     21 using namespace std;
     22 typedef unsigned int Uint;
     23 const int INF=0x3fffffff;
     24 ///==============struct declaration==============
     25 
     26 ///==============var declaration=================
     27 const int MAXN=30050;
     28 int n,q,tot=0,k,v,L,R;
     29 int siz[MAXN],son[MAXN],fa[MAXN],top[MAXN],val[MAXN],No[MAXN],depth[MAXN];
     30 int sum[MAXN*5],maxv[MAXN*5];
     31 vector <int> Edge[MAXN];
     32 ///==============function declaration============
     33 void dfs1(int x);void dfs2(int x);void Init();
     34 void Set_Seg(int o,int l,int r);
     35 void update(int o,int l,int r);
     36 int Query_Max(int o,int l,int r);
     37 int Query_Sum(int o,int l,int r);
     38 ///==============main code=======================
     39 int main()
     40 {
     41 #define FILE__
     42 #ifdef FILE__
     43    freopen("input","r",stdin);
     44    freopen("output","w",stdout);
     45 #endif
     46    scanf("%d",&n);
     47    for(int i=1;i<n;i++){
     48       int s,e;scanf("%d%d",&s,&e);
     49       Edge[s].push_back(e);Edge[e].push_back(s);
     50    }
     51    for(int i=1;i<=n;i++)   scanf("%d",val+i);
     52    depth[1]=1;top[1]=1;dfs1(1);dfs2(1);
     53    for(int i=1;i<=n;i++){
     54       v=val[i],k=No[i];
     55       Set_Seg(1,1,n);
     56    }
     57    scanf("%d",&q);
     58    while (q--){
     59       char cmd[10];scanf("%s",cmd);
     60       if (cmd[1]=='M'){///QMAX
     61          int _max=-INF;int u,v;
     62          scanf("%d%d",&u,&v);if (u==v) _max=val[u];
     63           _max=max(_max,val[u]);
     64           _max=max(_max,val[v]);///if the point locates at a top of a Heavy String
     65          while (u!=v){
     66             if (depth[top[u]]<depth[top[v]])  swap(u,v);///Make u is always deeper
     67             if (top[u]==top[v]){///Locate at the same Heavy String
     68                L=No[u],R=No[v];if (L>R) swap(L,R);L++;R--;
     69                if (L<=R)
     70                _max=max(_max,Query_Max(1,1,n));
     71                break;
     72             }
     73             if (top[u]==u){///Top of a heavy string
     74                u=fa[u];
     75                _max=max(_max,val[u]);
     76             }
     77             else{///middle of a heavy string
     78                L=No[top[u]],R=No[u];if (L>R) swap(L,R);R--;
     79                _max=max(_max,Query_Max(1,1,n));u=top[u];
     80             }
     81          }
     82          printf("%d
    ",_max);
     83       }
     84       else if (cmd[1]=='S'){///QSUM
     85          int _sum=0;int u,v;
     86          scanf("%d%d",&u,&v);
     87           _sum+=val[u];
     88          if (u!=v) _sum+=val[v];///if the point locates at a top of a Heavy String
     89          while (u!=v){
     90             if (depth[top[u]]<depth[top[v]])  swap(u,v);///Make u is always deeper
     91             if (top[u]==top[v]){///Locate at the same Heavy String
     92                L=No[v],R=No[u];if (L>R) swap(L,R);L++;R--;
     93                if (L<=R)
     94                _sum+=Query_Sum(1,1,n);
     95                break;
     96             }
     97             if (top[u]==u){///Top of a heavy string
     98                u=fa[u];
     99                if (u!=v)
    100                _sum+=val[u];
    101             }
    102             else{///middle of a heavy string
    103                L=No[top[u]],R=No[u];if (L>R) swap(L,R);R--;
    104                _sum+=Query_Sum(1,1,n);u=top[u];
    105             }
    106          }
    107          printf("%d
    ",_sum);
    108       }
    109       else if (cmd[1]=='H'){///Change
    110          scanf("%d%d",&k,&v);val[k]=v;k=No[k];
    111          Set_Seg(1,1,n);
    112       }
    113    }
    114    return 0;
    115 }
    116 ///================fuction code====================
    117 void dfs1(int x){
    118    siz[x]=1;son[x]=-1;
    119    for(int i=0;i<Edge[x].size();i++){
    120       int &e=Edge[x][i];
    121       if (fa[x]==e)  continue;
    122       fa[e]=x;depth[e]=depth[x]+1;dfs1(e);
    123       siz[x]+=siz[e];
    124       if (son[x]==-1||siz[son[x]]<siz[e])
    125          son[x]=e;
    126    }
    127 }
    128 void dfs2(int x){
    129    No[x]=++tot;
    130    if (siz[x]!=1) {
    131       top[son[x]]=top[x];
    132       dfs2(son[x]);
    133    }
    134    for(int i=0;i<Edge[x].size();i++){
    135       int &e=Edge[x][i];
    136       if (son[x]==e||fa[x]==e) continue;
    137       top[e]=e;dfs2(e);
    138    }
    139 }
    140 void Set_Seg(int o,int l,int r){
    141    int m=(l+r)>>1,lc=o*2,rc=o*2+1;
    142    if (l==r){
    143       sum[o]=maxv[o]=v;
    144       return;
    145    }
    146    if (m>=k)   Set_Seg(lc,l,m);
    147    else  Set_Seg(rc,m+1,r);
    148    update(o,l,r);
    149 }
    150 void update(int o,int l,int r){
    151    int lc=o*2,rc=o*2+1;
    152    sum[o]=sum[lc]+sum[rc];
    153    maxv[o]=max(maxv[lc],maxv[rc]);
    154 }
    155 int Query_Max(int o,int l,int r){
    156    if (L<=l&&r<=R)
    157       return maxv[o];
    158    int m=(l+r)>>1,lc=o*2,rc=o*2+1;
    159    int Left=-INF,Right=-INF;
    160    if (m>=L)   Left=Query_Max(lc,l,m);
    161    if (m<R)    Right=Query_Max(rc,m+1,r);
    162    return max(Left,Right);
    163 }
    164 int Query_Sum(int o,int l,int r){
    165    if (L<=l&&r<=R)
    166       return sum[o];
    167    int m=(l+r)>>1,lc=o*2,rc=o*2+1;
    168    int Left=0,Right=0;
    169    if (m>=L)   Left=Query_Sum(lc,l,m);
    170    if (m<R)    Right=Query_Sum(rc,m+1,r);
    171    return Left+Right;
    172 }
    BZOJ 1036
  • 相关阅读:
    服务器Jmail配置问题
    Silverlight视频教程、资源下载。如果你觉得看图文不够形象,不够生动,那就看看视频吧。
    AspNetPager,asp.net分页的最终解决方案!
    VS2008的Web Application——net 1.1 CodeBehind 模式的回归(非编译模式)
    修复Jscript(IE浏览器脚本引擎)异常
    SQL Server中查看SQL句子执行所用的时间
    SilverLight开发系列第1步:搭建开发环境
    SilverLight开发系列第2步:使用vs2008和Blend 2.5打造Hellow World程序
    谨慎使用Paypal一类的 支付 中介公司
    一个典型的数据库操作事务死锁分析
  • 原文地址:https://www.cnblogs.com/Houjikan/p/4322274.html
Copyright © 2011-2022 走看看