15 7 7 10 7 1 7 9 7 3 7 4 10 14 14 2 14 13 9 11 9 6 6 5 6 8 3 15 3 12 0 0
0 0 0 0 0 1 6 0 3 1 0 0 0 2 0
照样是带时间戳的树状数组,记得去年多校的时候宣姐死活YY不出来……orz,然后我提供了思路,但是不会写,今天终于把他写完了。
注意直接深搜会爆栈,于是乎学了下栈模拟递归的写法……orz。
代码
#include <stdio.h> #include <string.h> #include <stack> #include <vector> #include <algorithm> using namespace std; stack <int> s; int vis[100005]; int in[100005]; int ans[100005]; int n; vector <int> v[100005]; int lowbit(int t) { return t&(-t); } int Query(int t) { int sum=0; while(t>0) { sum+=in[t]; t-=lowbit(t); } return sum; } void Add(int t,int val) { while(t<=n) { in[t]+=val; t+=lowbit(t); } } void DFS(int t) { int tag; s.push(t); while(!s.empty()) { tag=s.top(); if (!vis[tag]) { vis[tag]=1; ans[tag]=Query(tag); } else if (v[tag].size()!=0) { if (vis[v[tag].back()]==0) s.push(v[tag].back()); v[tag].pop_back(); } else { ans[tag]=Query(tag)-ans[tag]; s.pop(); Add(tag,1); } } } int main() { int m,i,j,T,x,y; while(1) { scanf("%d%d",&n,&m); if (n==0 && m==0) break; for (i=0;i<=n;i++) { v[i].clear(); } for (i=0;i<n-1;i++) { scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } memset(in,0,sizeof(in)); memset(vis,0,sizeof(vis)); memset(ans,0,sizeof(ans)); DFS(m); for (i=1;i<n;i++) { printf("%d ",ans[i]); } printf("%d\n",ans[i]); } return 0; }