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

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 3427  Solved: 1429
    [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”的操作,每行输出一个整数表示要求输出的结果。

     
    分析:
      裸的树链剖分。注意一下,输入的节点权值的下标要改为在线段树上的节点下标。
     
      1 #include <set>
      2 #include <map>
      3 #include <list>
      4 #include <cmath>
      5 #include <queue>
      6 #include <stack>
      7 #include <string>
      8 #include <vector>
      9 #include <cstdio>
     10 #include <cstring>
     11 #include <iostream>
     12 #include <algorithm>
     13 
     14 using namespace std;
     15 
     16 typedef long long ll;
     17 typedef unsigned long long ull;
     18 
     19 #define debug puts("here")
     20 #define rep(i,n) for(int i=0;i<n;i++)
     21 #define rep1(i,n) for(int i=1;i<=n;i++)
     22 #define REP(i,a,b) for(int i=a;i<=b;i++)
     23 #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
     24 #define pb push_back
     25 #define RD(n) scanf("%d",&n)
     26 #define RD2(x,y) scanf("%d%d",&x,&y)
     27 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
     28 #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
     29 #define All(vec) vec.begin(),vec.end()
     30 #define MP make_pair
     31 #define PII pair<int,int>
     32 #define PQ priority_queue
     33 #define cmax(x,y) x = max(x,y)
     34 #define cmin(x,y) x = min(x,y)
     35 #define Clear(x) memset(x,0,sizeof(x))
     36 /*
     37 
     38 #pragma comment(linker, "/STACK:1024000000,1024000000")
     39 
     40 int size = 256 << 20; // 256MB
     41 char *p = (char*)malloc(size) + size;
     42 __asm__("movl %0, %%esp
    " :: "r"(p) );
     43 
     44 */
     45 
     46 /******** program ********************/
     47 
     48 const int MAXN = 100005;
     49 const int INF = 1e9;
     50 
     51 int val[MAXN];
     52 int po[MAXN],tol;
     53 int sz[MAXN],dep[MAXN],fa[MAXN],son[MAXN],tid[MAXN],top[MAXN];
     54 bool use[MAXN];
     55 int tot;
     56 int mx,msum;
     57 
     58 struct node{
     59     int y,next;
     60 }edge[MAXN];
     61 
     62 struct Tree{
     63     int l,r,mx,sum;
     64     inline int mid(){
     65         return (l+r)>>1;
     66     }
     67 }tree[MAXN<<2];
     68 
     69 inline void add(int x,int y){
     70     edge[++tol].y = y;
     71     edge[tol].next = po[x];
     72     po[x] = tol;
     73 }
     74 
     75 void dfsFind(int x,int pa,int depth){
     76     use[x] = true;
     77     dep[x] = depth;
     78     fa[x] = pa;
     79     sz[x] = 1;
     80     son[x] = 0;
     81 
     82     for(int i=po[x];i;i=edge[i].next){
     83         int y = edge[i].y;
     84         if(use[y])continue;
     85         dfsFind(y,x,depth+1);
     86         sz[x] += sz[y];
     87         if(sz[y]>sz[ son[x] ])
     88             son[x] = y;
     89     }
     90 }
     91 
     92 void dfsCon(int x,int pa){
     93     use[x] = true;
     94     tid[x] = ++ tot;
     95     top[x] = pa;
     96     if(son[x])
     97         dfsCon(son[x],pa);
     98     for(int i=po[x];i;i=edge[i].next){
     99         int y = edge[i].y;
    100         if(use[y])continue;
    101         dfsCon(y,y);
    102     }
    103 }
    104 
    105 inline void update(int rt){
    106     tree[rt].sum = tree[rt<<1].sum+tree[rt<<1|1].sum;
    107     tree[rt].mx = max( tree[rt<<1].mx , tree[rt<<1|1].mx );
    108 }
    109 
    110 void build(int l,int r,int rt){
    111     tree[rt].l = l;
    112     tree[rt].r = r;
    113     if(l==r){
    114         tree[rt].sum = tree[rt].mx = val[l];
    115         return;
    116     }
    117     int mid = tree[rt].mid();
    118     build(l,mid,rt<<1);
    119     build(mid+1,r,rt<<1|1);
    120 
    121     update(rt);
    122 }
    123 
    124 void modify(int pos,int c,int rt){
    125     if(tree[rt].l==tree[rt].r){
    126         tree[rt].sum = tree[rt].mx = c;
    127         return;
    128     }
    129     int mid = tree[rt].mid();
    130     if(pos<=mid)
    131         modify(pos,c,rt<<1);
    132     else
    133         modify(pos,c,rt<<1|1);
    134 
    135     update(rt);
    136 }
    137 
    138 void ask(int l,int r,int rt){
    139     if(tree[rt].l==l&&tree[rt].r==r){
    140         mx = max(mx,tree[rt].mx);
    141         //cmax( mx , tree[rt].mx );
    142         msum += tree[rt].sum;
    143         return;
    144     }
    145     int mid = tree[rt].mid();
    146     if(r<=mid)
    147         ask(l,r,rt<<1);
    148     else if(l>mid)
    149         ask(l,r,rt<<1|1);
    150     else{
    151         ask(l,mid,rt<<1);
    152         ask(mid+1,r,rt<<1|1);
    153     }
    154 }
    155 
    156 int main(){
    157 
    158 #ifndef ONLINE_JUDGE
    159     freopen("sum.in","r",stdin);
    160     //freopen("sum.out","w",stdout);
    161 #endif
    162 
    163     int n,m,x,y;
    164     while(cin>>n){
    165         Clear(po);
    166         tol = 1;
    167 
    168         REP(i,2,n){
    169             RD2(x,y);
    170             add(x,y);
    171             add(y,x);
    172         }
    173 
    174         Clear(use);
    175         dfsFind(1,1,1);
    176 
    177         Clear(use);
    178         tot = 0;
    179         dfsCon(1,1);
    180 
    181         rep1(i,n){
    182             RD(y);
    183             val[ tid[i] ] = y;
    184         }
    185 
    186         build(1,n,1);
    187 
    188         RD(m);
    189         char op[10];
    190         while(m--){
    191             scanf("%s%d%d",op,&x,&y);
    192             if(op[1]=='H'){
    193                 modify(tid[x],y,1);
    194             }else{
    195                 mx = -INF;
    196                 msum = 0;
    197 
    198                 while( top[x] != top[y] ){
    199                     if( dep[ top[x] ] < dep[ top[y] ] )
    200                         swap(x,y);
    201                     ask( tid[ top[x] ] , tid[x] , 1 );
    202                     x = fa[ top[x] ];
    203                 }
    204                 if(dep[x]>dep[y])
    205                     swap(x,y);
    206                 ask(tid[x],tid[y],1);
    207 
    208                 printf("%d
    ",op[1]=='M'?mx:msum);
    209             }
    210         }
    211     }
    212 
    213     return 0;
    214 }
     

    SPOJ 6779. Can you answer these queries VII

    给定一棵点权树,支持以下两种操作:

    • 1 u v: 询问 u, v 路径上的最大子序列和。((允许不取)
    • 2 u v d: 将 u, v 路径上的所有点的点权都修改为 d。

    Ural 1553. Caves and Tunnels

    给定一个 n 个结点的带点权的树,要求维护以下两种操作:

    • I u d: 将结点 u 的权值 + d。
    • G u v: 询问 u、v 所在路径上点权的最大值。

    spoj 2798 Query on a tree again!

    给出一棵树,节点只有两种颜色,初始时颜色为白色。有两种操作:

    • 0 i :询问节点1到i的路径上第一个是黑色的节点,没有为-1.
    • 1 v:节点v颜色反置。
     
  • 相关阅读:
    Ecshop去掉模版中随机出现Ecshop版权的方法
    ecshop邮件订阅按“订阅”没反应
    ecshop开发帮助
    ecshop循环计数
    ECSHOP购物车页面显示商品简单描述
    ecshop 函数列表大全
    ecshop 商品分类页 取得当前分类下的子分类方法
    ecshop调用指定分类和个数的文章列表
    thymeleaf中的th:assert用法
    thymeleaf中的模板布局
  • 原文地址:https://www.cnblogs.com/yejinru/p/3279613.html
Copyright © 2011-2022 走看看