• 【POJ3237】Tree(树链剖分+线段树)


    Description

    You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 throughN − 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:

    CHANGEiv Change the weight of the ith edge to v
    NEGATEab Negate the weight of every edge on the path from a to b
    QUERYab 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
     

     【题意】

    指定一颗树上有3个操作:

      询问操作,询问a点和b点之间的路径上最长的那条边的长度;

      取反操作,将a点和b点之间的路径权值都取相反数;

      变化操作,把某条边的权值x变成指定的值。

    【分析】

      人生第一道树剖题,调了好久啊,200+的代码还打了对拍= =

      就是裸的树链剖分+线段树啦。

      就是线段树打得不够熟练所以调了那么久,lazy标记不大会用~~

      

      树剖的主要过程就是两次的dfs,第一次求fa,第二次求top。询问过程就是一直跳,跳到两个东西在一条重链上去。

      因为某种特殊性质,所以他很快。。

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 10010
      8 #define INF 100000000
      9 
     10 int fa[Maxn],first[Maxn],size[Maxn],dep[Maxn],son[Maxn];
     11 int w[Maxn],top[Maxn];int wl;
     12 int b[Maxn][5];
     13 
     14 struct node
     15 {
     16     int x,y,c,next;
     17 }t[2*Maxn];int len;
     18 
     19 struct nnode
     20 {
     21     int l,r,lc,rc,mx,mn;
     22     bool lazy;
     23 }tr[2*Maxn];int tl;
     24 
     25 int mymax(int x,int y) {return x>y?x:y;}
     26 int mymin(int x,int y) {return x<y?x:y;}
     27 
     28 void ins(int x,int y,int c)
     29 {
     30     t[++len].x=x;t[len].y=y;t[len].c=c;
     31     t[len].next=first[x];first[x]=len;
     32 }
     33 
     34 void dfs1(int x,int f)
     35 {
     36     fa[x]=f;dep[x]=dep[f]+1;size[x]=1;
     37     son[x]=0;
     38     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
     39     {
     40         dfs1(t[i].y,x);
     41         size[x]+=size[t[i].y];
     42         if(size[t[i].y]>size[son[x]]) son[x]=t[i].y;
     43     }
     44 }
     45 
     46 void dfs2(int x,int tp)
     47 {
     48     w[x]=++wl;
     49     top[x]=tp;
     50     if(size[x]!=1) dfs2(son[x],tp);
     51     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x])
     52     {
     53         dfs2(t[i].y,t[i].y);
     54     }
     55 }
     56 
     57 int build(int l,int r)
     58 {
     59     int x=++tl;
     60     tr[x].l=l;tr[x].r=r;tr[x].mx=-INF;tr[x].mn=INF;tr[x].lazy=0;
     61     if(l!=r)
     62     {
     63         int mid=(l+r)>>1;
     64         tr[x].lc=build(l,mid);
     65         tr[x].rc=build(mid+1,r);
     66     }
     67     return x;
     68 }
     69 
     70 void upd(int x)
     71 {
     72     if(!tr[x].lazy) return;
     73     tr[x].lazy=0;
     74     int a=tr[x].mx;
     75     tr[x].mx=-tr[x].mn;tr[x].mn=-a;
     76     if(tr[x].l==tr[x].r) return;
     77     tr[tr[x].lc].lazy=!tr[tr[x].lc].lazy;
     78     tr[tr[x].rc].lazy=!tr[tr[x].rc].lazy;
     79 }
     80 
     81 void change(int x,int y,int c)
     82 {
     83     upd(x);
     84     if(tr[x].l==tr[x].r)
     85     {
     86         tr[x].mx=c;
     87         tr[x].mn=c;
     88         return;
     89     }
     90     int mid=(tr[x].l+tr[x].r)>>1;
     91     if(y<=mid) change(tr[x].lc,y,c);
     92     else change(tr[x].rc,y,c);
     93     upd(tr[x].lc);upd(tr[x].rc);
     94     tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx);
     95     tr[x].mn=mymin(tr[tr[x].lc].mn,tr[tr[x].rc].mn);
     96 }
     97 
     98 int qtree(int x,int l,int r)
     99 {
    100     upd(x);
    101     if(tr[x].l==l&&tr[x].r==r) return tr[x].mx;
    102     int mid=(tr[x].l+tr[x].r)>>1;
    103     if(r<=mid) return qtree(tr[x].lc,l,r);
    104     if(l>mid) return qtree(tr[x].rc,l,r);
    105     return mymax(qtree(tr[x].lc,l,mid),qtree(tr[x].rc,mid+1,r));
    106 }
    107 
    108 int query(int x,int y)
    109 {
    110     int tmp=-INF;
    111     int f1=top[x],f2=top[y];
    112     while(f1!=f2)
    113     {
    114         if(dep[f1]<dep[f2]) 
    115         {
    116             swap(f1,f2);
    117             swap(x,y);
    118         }
    119         tmp=mymax(qtree(1,w[f1],w[x]),tmp);
    120         x=fa[f1];
    121         f1=top[x];
    122     }
    123     if(x==y) return tmp;
    124     if(dep[x]<dep[y]) swap(x,y);
    125     return mymax(tmp,qtree(1,w[son[y]],w[x]));
    126 }
    127 
    128 void change2(int x,int l,int r)
    129 {
    130     upd(x);
    131     if(tr[x].l==l&&tr[x].r==r)
    132     {
    133         tr[x].lazy=!tr[x].lazy;
    134         upd(x);
    135         return;
    136     }
    137     int mid=(tr[x].l+tr[x].r)>>1;
    138     if(r<=mid) change2(tr[x].lc,l,r);
    139     else if(l>mid) change2(tr[x].rc,l,r);
    140     else
    141     {
    142         change2(tr[x].lc,l,mid);
    143         change2(tr[x].rc,mid+1,r);
    144     }
    145     upd(tr[x].lc);upd(tr[x].rc);
    146     tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx);
    147     tr[x].mn=mymin(tr[tr[x].lc].mn,tr[tr[x].rc].mn);
    148 }
    149 
    150 void negate1(int x,int y)
    151 {
    152     int f1=top[x],f2=top[y];
    153     while(f1!=f2)
    154     {
    155         if(dep[f1]<dep[f2]) 
    156         {
    157             swap(f1,f2);
    158             swap(x,y);
    159         }
    160         change2(1,w[f1],w[x]);
    161         x=fa[f1];
    162         f1=top[x];
    163     }
    164     if(x==y) return;
    165     if(dep[x]<dep[y]) swap(x,y);
    166     change2(1,w[son[y]],w[x]);
    167 }
    168 
    169 int main()
    170 {
    171     int T;
    172     scanf("%d",&T);
    173     while(T--)
    174     {
    175         int n;
    176         scanf("%d",&n);
    177         memset(first,0,sizeof(first));
    178         len=0;
    179         for(int i=1;i<n;i++)
    180         {
    181             int x,y,c;
    182             scanf("%d%d%d",&x,&y,&c);
    183             b[i][0]=x;b[i][1]=y;b[i][2]=c;
    184             ins(x,y,c);ins(y,x,c);
    185         }
    186         dep[0]=0;size[0]=0;
    187         dfs1(1,0);wl=0;
    188         dfs2(1,1);
    189         char s[10];
    190         tl=0;
    191         build(1,wl);
    192         for(int i=1;i<n;i++)
    193         {
    194             if(dep[b[i][0]]<dep[b[i][1]]) swap(b[i][0],b[i][1]);
    195             change(1,w[b[i][0]],b[i][2]);
    196         }
    197         while(1)
    198         {
    199             scanf("%s",s);
    200             if(s[0]=='D') break;
    201             if(s[0]=='Q')
    202             {
    203                 int x,y;
    204                 scanf("%d%d",&x,&y);
    205                 printf("%d
    ",query(x,y));
    206             }
    207             else if(s[0]=='C')
    208             {
    209                 int x,y;
    210                 scanf("%d%d",&x,&y);
    211                 change(1,w[b[x][0]],y);//单点修改
    212             }
    213             else
    214             {
    215                 int x,y;
    216                 scanf("%d%d",&x,&y);
    217                 negate1(x,y);
    218             }
    219         }
    220     }
    221     return 0;
    222 }
    [POJ3237]

    2016-05-08 14:50:31

  • 相关阅读:
    【已解决】Makefile执行过程中出错:make: *** No rule to make target ` ‘, needed by xxx. Stop(转载)
    eclipse导入工程报Invalid project description(转载)
    基于Linux的v4l2视频架构驱动编写(转载)
    在eclipse中如何在大量项目中查找指定文件(转载)
    Ubuntu下FileZilla的安装(转载)
    创建 /dev/video0 节点 (转载)
    python函数-迭代器&生成器
    前端第三篇---前端基础之JavaScript
    前端第二篇---前端基础之CSS
    块级元素和行内元素使用心得汇总
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5470636.html
Copyright © 2020-2023  润新知