[后序遍历][堆][倍增] Jzoj P4811

 

Description

 

Input

Output

 

Sample Input

5 4
1 2
1 3
3 4
3 5
1 4
2 4
1 2
2 5

Sample Output

3
1
1
2
 

Data Constraint


 

Hint

 

 

题解

  • 首先,我们很容易就可以发现,每个人的走法就是后序遍历的走法
  • 询问删掉一个人之后又多少个人变化,也就是该点到根路径上人的数量
  • 那么我们就可以用堆维护房间,然后用倍增往上跳找人数

代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <vector>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8 const int N=100010;
 9 int n,t,tot,cnt,ans,dfx[N],d[N],p[N],heap[N*4],deep[N],f[N][20];
10 bool bz[N];
11 vector<int> a[N];
12 bool cmp(int x,int y) { return dfx[x]<dfx[y]; }
13 void dfs(int x,int fa)
14 {
15     f[x][0]=fa,deep[x]=deep[fa]+1;
16     for (int i=0;i<a[x].size();i++) if (a[x][i]!=fa) dfs(a[x][i],x); 
17     dfx[x]=++cnt;
18 }
19 void insert(int x)
20 {
21     heap[++tot]=x;
22     for (int i=tot;i>1&&p[heap[i]]<p[heap[i/2]];i/=2) swap(heap[i],heap[i/2]);
23 }
24 int get()
25 {
26     int x=heap[1],i=1;
27     heap[1]=heap[tot],heap[tot--]=0;
28     while (1)
29     {
30         int l=i*2,r=i*2+1,m;
31         if (!(p[heap[i]]>p[heap[l]]&&l<=tot||p[heap[i]]>p[heap[r]]&&r<=tot)) break;
32         if (r>tot||p[heap[l]]<p[heap[r]]) m=l; else m=r;
33         swap(heap[i],heap[m]),i=m;
34     }
35     return x;
36 }
37 int jump(int x)
38 {
39     for (int i=log2(deep[x]);i>=0;i--) if (bz[f[x][i]]) x=f[x][i];
40     return x;
41 }
42 int main()
43 {
44     scanf("%d%d",&n,&t);
45     for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),a[x].push_back(y),a[y].push_back(x);
46     for (int i=1;i<=n;i++) d[i]=i,sort(a[i].begin(),a[i].end());
47     dfs(1,0);
48     for (int j=1;j<=log2(n);j++) for (int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1];
49     sort(d+1,d+n+1,cmp);
50     for (int i=1;i<=n;i++) p[d[i]]=i;
51     for (int i=1;i<=n;i++) insert(i);
52     for (int i=1,x,y,op;i<=t;i++)
53     {
54         scanf("%d%d",&op,&x);
55         if (op==1) 
56         {    
57             for (;x;x--) bz[ans=get()]=1;
58             printf("%d\n",ans);
59         }
60         else printf("%d\n",deep[x]-deep[y=jump(x)]),insert(y),bz[y]=0;
61     }
62 }

 

posted @ 2019-07-03 16:27  BEYang_Z  阅读(212)  评论(0编辑  收藏  举报