zoukankan      html  css  js  c++  java
  • POJ 3237 Tree

    Tree

    Time Limit: 5000ms
    Memory Limit: 131072KB
    This problem will be judged on PKU. Original ID: 3237
    64-bit integer IO format: %lld      Java class name: Main
     
    You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:
    1. CHANGE i v: Change the weight of the ith edge to v
    2. NEGATE a b: Negate the weight of every edge on the path from a to b
    3. QUERY a b: Find the maximum weight of edges on the path from a to b

    Input

    The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.

    Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers ab and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case.

    Output

    For each “QUERY” instruction, output the result on a separate line.

    Sample Input

    1
    
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE

    Sample Output

    1
    3

    Source

     
    解题:树链剖分
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 const int INF = 0x3f3f3f3f;
      7 const int maxn = 10010;
      8 struct arc{
      9     int to,w,next;
     10     arc(int x = 0,int y = 0,int z = -1){
     11         to = x;
     12         w = y;
     13         next = z;
     14     }
     15 }e[maxn<<1];
     16 struct node{
     17     int lt,rt,maxval,lazy,minval;
     18 }tree[maxn<<2];
     19 int head[maxn],fa[maxn],top[maxn],dep[maxn];
     20 int siz[maxn],son[maxn],loc[maxn];
     21 int clk,tot,n;
     22 void add(int u,int v,int w){
     23     e[tot] = arc(v,w,head[u]);
     24     head[u] = tot++;
     25 }
     26 void FindHeavyEdge(int u,int father,int depth){
     27     fa[u] = father;
     28     dep[u] = depth;
     29     son[u] = -1;
     30     siz[u] = 1;
     31     for(int i = head[u]; ~i; i = e[i].next){
     32         if(e[i].to == father) continue;
     33         FindHeavyEdge(e[i].to,u,depth + 1);
     34         siz[u] += siz[e[i].to];
     35         if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
     36             son[u] = e[i].to;
     37     }
     38 }
     39 void ConnectHeavyEdge(int u,int ancestor){
     40     top[u] = ancestor;
     41     loc[u] = clk++;
     42     if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
     43     for(int i = head[u]; ~i; i = e[i].next){
     44         if(e[i].to == fa[u] || e[i].to == son[u]) continue;
     45         ConnectHeavyEdge(e[i].to,e[i].to);
     46     }
     47 }
     48 void build(int lt,int rt,int v){
     49     tree[v].lt = lt;
     50     tree[v].rt = rt;
     51     tree[v].lazy = 1;
     52     tree[v].maxval = tree[v].minval = 0;
     53     if(lt == rt) return;
     54     int mid = (lt + rt)>>1;
     55     build(lt,mid,v<<1);
     56     build(mid + 1,rt,v<<1|1);
     57 }
     58 inline void pushdown(int v){
     59     if(tree[v].lazy == -1){
     60         tree[v<<1].lazy *= -1;
     61         tree[v<<1|1].lazy *= -1;
     62         swap(tree[v<<1].minval,tree[v<<1].maxval);
     63         tree[v<<1].maxval = -tree[v<<1].maxval;
     64         tree[v<<1].minval = -tree[v<<1].minval;
     65         swap(tree[v<<1|1].maxval,tree[v<<1|1].minval);
     66         tree[v<<1|1].maxval = -tree[v<<1|1].maxval;
     67         tree[v<<1|1].minval = -tree[v<<1|1].minval;
     68         tree[v].lazy = 1;
     69     }
     70 }
     71 inline void pushup(int v){
     72     tree[v].maxval = max(tree[v<<1].maxval,tree[v<<1|1].maxval);
     73     tree[v].minval = min(tree[v<<1].minval,tree[v<<1|1].minval);
     74 }
     75 void change(int pos,int val,int v){
     76     if(tree[v].lt == tree[v].rt){
     77         tree[v].maxval = tree[v].minval = val;
     78         return;
     79     }
     80     pushdown(v);
     81     if(pos <= tree[v<<1].rt) change(pos,val,v<<1);
     82     if(pos >= tree[v<<1|1].lt) change(pos,val,v<<1|1);
     83     pushup(v);
     84 }
     85 int Negate(int lt,int rt,int v){
     86     if(lt <= tree[v].lt && rt >= tree[v].rt){
     87         tree[v].lazy *= -1;
     88         swap(tree[v].maxval,tree[v].minval);
     89         tree[v].maxval = -tree[v].maxval;
     90         tree[v].minval = -tree[v].minval;
     91         return 0;
     92     }
     93     pushdown(v);
     94     if(lt <= tree[v<<1].rt) Negate(lt,rt,v<<1);
     95     if(rt >= tree[v<<1|1].lt) Negate(lt,rt,v<<1|1);
     96     pushup(v);
     97     return 0;
     98 }
     99 int query(int lt,int rt,int v){
    100     if(lt <= tree[v].lt && rt >= tree[v].rt) return tree[v].maxval;
    101     pushdown(v);
    102     int ret = -INF;
    103     if(lt <= tree[v<<1].rt) ret = query(lt,rt,v<<1);
    104     if(rt >= tree[v<<1|1].lt) ret = max(ret,query(lt,rt,v<<1|1));
    105     return ret;
    106 }
    107 int CAO(int u,int v,int (*f)(int,int,int)){
    108     int ret = -INF;
    109     while(top[u] != top[v]){
    110         if(dep[top[u]] < dep[top[v]]) swap(u,v);
    111         ret = max(ret,f(loc[top[u]],loc[u],1));
    112         u = fa[top[u]];
    113     }
    114     if(u == v) return ret;
    115     if(dep[u] > dep[v]) swap(u,v);
    116     ret = max(ret,f(loc[son[u]],loc[v],1));
    117     return ret;
    118 }
    119 int main(){
    120     int kase,u,v,w;
    121     scanf("%d",&kase);
    122     while(kase--){
    123         scanf("%d",&n);
    124         tot = clk = 0;
    125         memset(head,-1,sizeof head);
    126         for(int i = 1; i < n; ++i){
    127             scanf("%d%d%d",&u,&v,&w);
    128             add(u,v,w);
    129             add(v,u,w);
    130         }
    131         FindHeavyEdge(1,0,0);
    132         ConnectHeavyEdge(1,1);
    133         build(0,clk-1,1);
    134         for(int i = 0; i < tot; i += 2){
    135             u = e[i].to;
    136             v = e[i + 1].to;
    137             if(dep[u] < dep[v]) swap(u,v);
    138             change(loc[u],e[i].w,1);
    139         }
    140         char op[10];
    141         while(~scanf("%s",op)){
    142             if(op[0] == 'D') break;
    143             if(op[0] == 'Q'){
    144                 scanf("%d%d",&u,&v);
    145                 printf("%d
    ",CAO(u,v,query));
    146             }else if(op[0] == 'C'){
    147                 scanf("%d%d",&u,&w);
    148                 int ith = (u - 1)*2;
    149                 if(dep[e[ith].to] < dep[e[ith+1].to]) ith++;
    150                 change(loc[e[ith].to],w,1);
    151             }else if(op[0] == 'N'){
    152                 scanf("%d%d",&u,&v);
    153                 CAO(u,v,Negate);
    154             }
    155         }
    156     }
    157     return 0;
    158 }
    View Code
  • 相关阅读:
    HDU
    android 博客园
    android105 jni概念
    android104 帧动画,补间动画,属性动画
    requestFocusFromTouch , requestFocus
    android103 内容观察者
    android102 查询,插入联系人
    android101 获取、备份、插入短信
    android100 自定义内容提供者
    android99 拍照摄像
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4844820.html
Copyright © 2011-2022 走看看