JZOJ 4811. 排队
题目
分析
-
这道题一看应该是个模拟题
-
但是我们需要优化
-
首先我们要跑一个dfs,讲树的优先级跑出来
-
然后我们开一个优先队列
-
讲优先级的下标压进队列
-
然后我们用倍增优化我们的向上找第一个被标记的点
- 结果就是直接的深度
代码
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include <queue> 5 #include<cstdio> 6 using namespace std; 7 const int N=100010; 8 int n,t,tot,cnt,ans,dfx[N],d[N],p[N],deep[N],f[N][20]; 9 bool bz[N]; 10 priority_queue<int,vector<int>,greater<int> > q; 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 int main () 20 { 21 cin>>n>>t; 22 for (int i=1,x,y;i<=n-1;i++) 23 { 24 scanf("%d %d",&x,&y); 25 a[x].push_back(y); 26 a[y].push_back(x); 27 } 28 for (int i=1;i<=n;i++) d[i]=i,sort(a[i].begin(),a[i].end()); 29 dfs(1,0); 30 for (int i=1;i<=18;i++) 31 for (int j=1;j<=n;j++) 32 f[j][i]=f[f[j][i-1]][i-1]; 33 sort(d+1,d+1+n,cmp); 34 for (int i=1;i<=n;i++) p[d[i]]=i; 35 for (int i=1;i<=n;i++) q.push(i); 36 for (int i=1,x,y,op;i<=t;i++) 37 { 38 scanf("%d %d",&op,&x); 39 if(op==1) 40 { 41 for (;x;x--) bz[ans=d[q.top()]]=1,q.pop(); 42 printf("%d\n",ans); 43 } 44 else 45 { 46 int a=x; 47 for (int i=18;i>=0;i--) 48 if (bz[f[a][i]]) a=f[a][i]; 49 bz[a]=0,q.push(p[a]); 50 printf("%d\n",deep[x]-deep[a]); 51 } 52 } 53 }
为何要逼自己长大,去闯不该闯的荒唐