• 1103. [POI2007]MEG-Megalopolis【树链剖分】


    Description

      在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了。
    不过,她经常回忆起以前在乡间漫步的情景。昔日,乡下有依次编号为1..n的n个小村庄,某些村庄之间有一些双
    向的土路。从每个村庄都恰好有一条路径到达村庄1(即比特堡)。并且,对于每个村庄,它到比特堡的路径恰好
    只经过编号比它的编号小的村庄。另外,对于所有道路而言,它们都不在除村庄以外的其他地点相遇。在这个未开
    化的地方,从来没有过高架桥和地下铁道。随着时间的推移,越来越多的土路被改造成了公路。至今,Blue Mary
    还清晰地记得最后一条土路被改造为公路的情景。现在,这里已经没有土路了——所有的路都成为了公路,而昔日
    的村庄已经变成了一个大都市。 Blue Mary想起了在改造期间她送信的经历。她从比特堡出发,需要去某个村庄,
    并且在两次送信经历的间隔期间,有某些土路被改造成了公路.现在Blue Mary需要你的帮助:计算出每次送信她需
    要走过的土路数目。(对于公路,她可以骑摩托车;而对于土路,她就只好推车了。)

    Input

      第一行是一个数n(1 < = n < = 2 50000).以下n-1行,每行两个整数a,b(1 < =  a以下一行包含一个整数m
    (1 < = m < = 2 50000),表示Blue Mary曾经在改造期间送过m次信。以下n+m-1行,每行有两种格式的若干信息
    ,表示按时间先后发生过的n+m-1次事件:若这行为 A a b(a若这行为 W a, 则表示Blue Mary曾经从比特堡送信到
    村庄a。

    Output

      有m行,每行包含一个整数,表示对应的某次送信时经过的土路数目。

    Sample Input

    5
    1 2
    1 3
    1 4
    4 5
    4
    W 5
    A 1 4
    W 5
    A 4 5
    W 5
    W 2
    A 1 2
    A 1 3

    Sample Output

    2
    1
    0
    1

    HINT

    就是一道裸的树链剖分啊……
    过程中唯一的一点小麻烦(好像也算不上麻烦)
    就是把边看成点做0v0
    所以Change的时候最后当两个点在同一条重链上就修改
    Update(1,1,n,T_NUM[Son[x]],T_NUM[y],1);

      1 #include<iostream>
      2 #include<cstdio>
      3 #define MAX (250000+10)
      4 using namespace std;
      5 
      6 int Depth[MAX],Son[MAX],Father[MAX],Sum[MAX];
      7 int head[MAX],num_edge,sum;
      8 int Top[MAX],T_NUM[MAX],n;
      9 struct node
     10 {
     11     int to,next;
     12 }edge[MAX*2];
     13 struct node1
     14 {
     15     int add,down;
     16 }Segt[MAX*4];
     17 
     18 void Add(int u,int v)
     19 {
     20     edge[++num_edge].to=v;
     21     edge[num_edge].next=head[u];
     22     head[u]=num_edge;
     23 }
     24 
     25 void Dfs1(int x)
     26 {
     27     Depth[x]=Depth[Father[x]]+1;
     28     Sum[x]=1;
     29     for (int i=head[x];i!=0;i=edge[i].next)
     30         if (edge[i].to!=Father[x])
     31         {
     32             Father[edge[i].to]=x;
     33             Dfs1(edge[i].to);
     34             Sum[x]+=Sum[edge[i].to];
     35             if (Son[x]==0 || Sum[Son[x]]<Sum[edge[i].to])
     36                 Son[x]=edge[i].to;
     37         }
     38 }
     39 
     40 void Dfs2(int x,int pre)
     41 {
     42     T_NUM[x]=++sum;
     43     Top[x]=pre;
     44     if (Son[x]!=0)
     45         Dfs2(Son[x],pre);
     46     for (int i=head[x];i!=0;i=edge[i].next)
     47     {
     48         if (edge[i].to!=Father[x] && edge[i].to!=Son[x])
     49             Dfs2(edge[i].to,edge[i].to);
     50     }
     51 }
     52 
     53 void Pushdown(int node,int l,int r)
     54 {
     55     if (Segt[node].down!=0)
     56     {
     57         Segt[node*2].down=Segt[node].down;
     58         Segt[node*2+1].down=Segt[node].down;
     59         int mid=(l+r)/2;
     60         Segt[node*2].add=Segt[node].down*(mid-l+1);
     61         Segt[node*2].add=Segt[node].down*(r-mid);
     62         Segt[node].down=0;
     63     }
     64 }
     65 
     66 void Update(int node,int l,int r,int l1,int r1,int k)
     67 {
     68     if (r<l1 || l>r1)
     69         return;
     70     if (l1<=l && r<=r1)
     71     {
     72         Segt[node].add=(r-l+1)*k;
     73         Segt[node].down=k;
     74         return;
     75     }
     76     Pushdown(node,l,r);
     77     int mid=(l+r)/2;
     78     Update(node*2,l,mid,l1,r1,k);
     79     Update(node*2+1,mid+1,r,l1,r1,k);
     80     Segt[node].add=Segt[node*2].add+Segt[node*2+1].add;
     81 }
     82 
     83 int Query(int node,int l,int r,int l1,int r1)
     84 {
     85     if (r<l1 || l>r1)
     86         return 0;
     87     if (l1<=l && r<=r1)
     88         return Segt[node].add;
     89     Pushdown(node,l,r);
     90     int mid=(l+r)/2;
     91     return Query(node*2,l,mid,l1,r1)+
     92            Query(node*2+1,mid+1,r,l1,r1);
     93     
     94 }
     95 
     96 void Change(int x,int y)
     97 {
     98     int fx=Top[x],fy=Top[y];
     99     while (fx!=fy)
    100     {
    101         if (Depth[fx]<Depth[fy])
    102             swap(fx,fy),swap(x,y);
    103         Update(1,1,n,T_NUM[fx],T_NUM[x],1);
    104         x=Father[fx];fx=Top[x];
    105     }
    106     if (Depth[x]>Depth[y])
    107         swap(x,y);
    108     Update(1,1,n,T_NUM[Son[x]],T_NUM[y],1);
    109 }
    110 
    111 int Ask(int x)//0为土路1为公路 
    112 {
    113     int ans=0,fx=Top[x],sum=Depth[x]-1;
    114     while (x!=0)
    115     {
    116         ans+=Query(1,1,n,T_NUM[fx],T_NUM[x]);
    117         x=Father[fx],fx=Top[x];
    118     }
    119     return sum-ans;
    120 }
    121 
    122 int main()
    123 {
    124     int u,v,m,x,y;
    125     char p;
    126     scanf("%d",&n);
    127     for (int i=1;i<=n-1;++i)
    128     {
    129         scanf("%d%d",&u,&v);
    130         Add(u,v);
    131         Add(v,u);
    132     }
    133     Dfs1(1);
    134     Dfs2(1,1);
    135     scanf("%d",&m);
    136     for (int i=1;i<=n+m-1;++i)
    137     {
    138         scanf("%c",&p);
    139         while (p!='W' && p!='A')
    140             scanf("%c",&p);
    141         if (p=='W')
    142             scanf("%d",&x),printf("%d
    ",Ask(x));
    143         else
    144             scanf("%d%d",&x,&y),Change(x,y);
    145     }
    146 }
  • 相关阅读:
    [BZOJ] IOI2015 Boxes纪念品盒
    [BZOJ] 聚会
    [BZOJ] 地精部落
    [BZOJ] 最长距离
    正则
    cookie实例 记住用户名密码
    cookie封装
    碎片整合 例子
    闭包 tab切换 实例
    闭包
  • 原文地址:https://www.cnblogs.com/refun/p/8678610.html
Copyright © 2020-2023  润新知