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 41 22 32 44 52 12 51 22 5

Output

032

正解:分块+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\n",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 }
时间: 2024-10-03 02:21:20

codeforces 342E :Xenia and Tree的相关文章

【CodeForces】E. Xenia and Tree(分块 + LCA)

对于两个操作,对于操作1,每次储存要修改的点,直到存了sqrt(m)个点的时候进行更新,并将图重建一次(重新记录每个点到最近染色点的距离) 对于操作2,利用LCA求现在存着的点(也就是还没有更新到图上的点)和这个点的距离的最小值以及这个点在当前图中和最近的染色的那个点的距离. 话说LCA真是个好东西=  =!这几天补一补去 题解在这里:http://codeforces.com/blog/entry/8800 #include<cmath> #include<queue> #inc

Codeforces 29D Ant on the Tree 树的遍历 dfs序

题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径,要求遍历叶子节点时按照给定叶子节点的先后顺序访问. 思路: 给每个节点加一个优先级. 把最后一个叶子节点到父节点的路径上的点优先级改为1 把倒数第二个叶子节点到父节点的路径上的点优先级改为2 如此每个点就有一个优先级,每个访问儿子节点时先访问优先级大的即可 对于无解的判断:得到的欧拉序列不满足输入的叶子节点顺序即是无解. #include <cstdio> #

codeforces 514E Darth Vader and Tree (dp+快速幂)

codeforces 514E Darth Vader and Tree (dp+快速幂) 题意: 有一棵树,每个节点有n个儿子,给出父亲到每个儿子的距离di,问离祖先距离不超过x的子孙有多少个(子孙包括祖先)对1e9+7取模. 限制: 1 <= n <= 1e5; 0 <= x <= 1e9; 1 <= di <= 100 思路: 因为di <= 100,所以可以用快速幂来处理这道题, 大概过程为:先用dp算出前100的答案,剩下的用快速幂来处理.

codeforces 220 C. Game on Tree

题目链接 codeforces 220 C. Game on Tree 题解 对于 1节点一定要选的 发现对于每个节点,被覆盖切选中其节点的概率为祖先个数分之一,也就是深度分之一 代码 #include<cstdio> #include<algorithm> const int maxn = 1000007; struct node { int u,v,next; } edge[maxn << 1] ; int head[maxn],num = 0; inline vo

Codeforces 449D:Jzzhu and Numbers

Codeforces 449D:Jzzhu and Numbers 题目链接:http://codeforces.com/problemset/status?friends=on 题目大意:给出$n$个数,求有多少种组合使得$a_{i_1}\&a_{i_2}\&...\&a_{i_k}=0(0 \leqslant i < n)$,答案对$10^9+7$取模. 容斥原理+DP 设位与$(\&)$后二进制表示中有$k$个$1$的组合数为$A_k$,则有, $A_0=$所有

Codeforces 757B:Bash&#39;s Big Day(分解因子+Hash)

http://codeforces.com/problemset/problem/757/B 题意:给出n个数,求一个最大的集合并且这个集合中的元素gcd的结果不等于1. 思路:一开始把素数表打出来,发现有9k+个数,不能暴力枚举.发现O(sqrt(n)*n)似乎可行,就枚举因子,然后出现过的因子就在Hash[]加1,最后枚举素数表里的元素,找出现次数最多的,因为那些数都可以映射在素数表里面.注意最少的ans是1. 1 #include <cstdio> 2 #include <algo

Codeforces 754E:Dasha and cyclic table

Codeforces 754E:Dasha and cyclic table 题目链接:http://codeforces.com/problemset/problem/754/E 题目大意:$A$矩阵($size(A)=n \times m$,仅含'a'-'z')在整个平面做周期延拓,问$B$矩阵($size(B)=r \times c$,包含'a'-'z'及'?','?'为通配符)在哪些位置能与$A$矩阵匹配.输出$n \times m$的01矩阵,1表示在该位置匹配. 枚举+bitset常

leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)

题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 说明: 1)实现与根据先序和中序遍历构造二叉树相似,题目参考请进 算法思想 中序序列:C.B.E.D.F.A.H.G.J.I 后序序列:C.E.F.D.B.H.J.I.G.A 递归思路: 根据后序遍历的特点,知道后序

Ext.Net学习笔记22:Ext.Net Tree 用法详解

Ext.Net学习笔记22:Ext.Net Tree 用法详解 上面的图片是一个简单的树,使用Ext.Net来创建这样的树结构非常简单,代码如下: <ext:TreePanel runat="server"> <Root> <ext:Node Text="根节点" Expanded="true"> <Children> <ext:Node Text="节点1" Expand