zoukankan      html  css  js  c++  java
  • codeforces 342E :Xenia and Tree

    Description

    Xenia the programmer has a tree consisting of n nodes. We will consider the tree nodes indexed from 1 to n. We will also consider the first node to be initially painted red, and the other nodes — to be painted blue.

    The distance between two tree nodes v and u is the number of edges in the shortest path between v and u.

    Xenia needs to learn how to quickly execute queries of two types:

    1. paint a specified blue node in red;
    2. calculate which red node is the closest to the given one and print the shortest distance to the closest red node.

    Your task is to write a program which will execute the described queries.

    Input

    The first line contains two integers n and m (2 ≤ n ≤ 105, 1 ≤ m ≤ 105) — the number of nodes in the tree and the number of queries. Next n - 1 lines contain the tree edges, the i-th line contains a pair of integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — an edge of the tree.

    Next m lines contain queries. Each query is specified as a pair of integers ti, vi (1 ≤ ti ≤ 2, 1 ≤ vi ≤ n). If ti = 1, then as a reply to the query we need to paint a blue node vi in red. If ti = 2, then we should reply to the query by printing the shortest distance from some red node to node vi.

    It is guaranteed that the given graph is a tree and that all queries are correct.

    Output

    For each second type query print the reply in a single line.

    Examples
    Input
    5 4
    1 2
    2 3
    2 4
    4 5
    2 1
    2 5
    1 2
    2 5
    Output
    0
    3
    2



    正解:分块+RMQ求LCA
    解题报告:
      上次考试的原题...

      正解可以写动态树分治,但同时YMDragon写的也是XYK给出的标解就是把操作分块。大概讲一下吧,就是每根号个修改都作为一个整体,丢到一个数组里面,每次询问是当前这个结点的最优解,并且把当前结点数组里面每个待更新的结点求一下距离更新一下答案。然后每当数组里面的元素多于根号个就全部取出来然后update一下整棵树,BFS一遍,相当于是多源最短路。这样可以保证复杂度。

      我发现我缺乏对根号算法的思考,平时会做会想,但是真正考试的时候很少往分块或者莫队上想,这是我需要提高和锻炼的。



     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 using namespace std;
    14 typedef long long LL;
    15 const int MAXN = 100011;
    16 const int inf = 1LL<<30;
    17 const int MAXM = 200011;
    18 #define RG register
    19 const int SIZE = 600;
    20 int n,m,ecnt,ans;
    21 int first[MAXN],to[MAXM],next[MAXM];
    22 int deep[MAXN],id[MAXN];
    23 int dui[MAXN],head,tail,dis[MAXN],ans_dis[MAXN];
    24 int D[MAXN*3],belong[MAXN*3];
    25 int ST[MAXN*3][20],mi[20];
    26 int stack[SIZE+12],top;
    27 
    28 inline int getint()
    29 {
    30        RG int w=0,q=0; RG char c=getchar();
    31        while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 
    32        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
    33 }
    34 
    35 inline void dfs(int x,int fa){
    36     D[++ecnt]=x; id[x]=ecnt;
    37     for(int i=first[x];i;i=next[i]) {
    38     RG int v=to[i]; if(v==fa) continue;
    39     deep[v]=deep[x]+1; dfs(v,x); 
    40     D[++ecnt]=x;
    41     }
    42 }
    43 
    44 inline void build(){
    45     belong[1]=0;  for(int i=2;i<=ecnt;i++) belong[i]=belong[i/2]+1;
    46     mi[0]=1; for(int i=1;i<=19;i++) mi[i]=mi[i-1]*2;
    47     for(int i=1;i<=ecnt;i++) ST[i][0]=D[i];
    48     for(int j=1;j<=19;j++) for(int i=1;i+mi[j-1]-1<=ecnt;i++) { if(deep[ST[i+mi[j-1]][j-1]]>deep[ST[i][j-1]]) ST[i][j]=ST[i][j-1]; else ST[i][j]=ST[i+mi[j-1]][j-1]; }
    49 }
    50 
    51 inline int lca(int x,int y){
    52     int f1=id[x],f2=id[y]; if(f1>f2) swap(f1,f2);
    53     int ll=f2-f1+1,lr=belong[ll]; 
    54     if(deep[ST[f1][lr]]>deep[ST[f2-(1<<lr)+1][lr]]) return ST[f2-(1<<lr)][lr];
    55     else return ST[f1][lr];
    56 }
    57 
    58 inline void work(){
    59     n=getint(); m=getint(); RG int x,y;
    60     for(RG int i=2;i<=n;i++) {
    61         x=getint(); y=getint();
    62     next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y;
    63     next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x;
    64     }
    65     ecnt=0; dfs(1,0); build();
    66     for(RG int i=1;i<=n;i++) ans_dis[i]=deep[i];
    67     RG int ljh,u;
    68     while(m--) {
    69     ljh=getint();
    70     if(ljh==2) {
    71         x=getint(); for(RG int i=1;i<=top;i++) ans_dis[x]=min(ans_dis[x],deep[x]+deep[stack[i]]-deep[lca(x,stack[i])]*2);
    72         printf("%d
    ",ans_dis[x]);
    73     }
    74     else {
    75         x=getint(); if(x==0) continue; stack[++top]=x;
    76         if(top>=SIZE) {
    77         head=0; tail=0;    for(RG int i=1;i<=n;i++) dis[i]=inf;
    78         for(RG int i=1;i<=top;i++) dui[++tail]=stack[i],dis[stack[i]]=0;
    79         top=0;
    80         while(head<tail) {
    81             head++; u=dui[head]; ans_dis[u]=min(ans_dis[u],dis[u]);
    82             for(RG int i=first[u];i;i=next[i]) {
    83             RG int v=to[i];
    84             if(dis[v]==inf) {
    85                 dis[v]=dis[u]+1; dui[++tail]=v;
    86             }
    87             }
    88         }
    89         }
    90     }
    91     }
    92 }
    93 
    94 int main()
    95 {
    96   work();
    97   return 0;
    98 }
  • 相关阅读:
    第三方驱动备份与还原
    Greenplum 解决 gpstop -u 指令报错
    yum安装(卸载)本地rpm包的方法(卸载本地安装的greenplum 5.19.rpm)
    Java JUC(java.util.concurrent工具包)
    netty 详解(八)基于 Netty 模拟实现 RPC
    netty 详解(七)netty 自定义协议解决 TCP 粘包和拆包
    netty 详解(六)netty 自定义编码解码器
    netty 详解(五)netty 使用 protobuf 序列化
    netty 详解(四)netty 开发 WebSocket 长连接程序
    netty 详解(三)netty 心跳检测机制案例
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5921094.html
Copyright © 2011-2022 走看看