cf980E TheNumberGames (贪心+倍增)
由于是$2^i$,所以一定要尽量留下来编号大的点
我们干脆就让n号点做树根,它是一定要留的
然后如果要留i的话,i一直到根的路径也都要留。所以只要判断一下够不够把这个路径上还没有留的都留下来
记录下已经留下来的点,然后倍增来找就可以了
然后如果可以的话,可以一个一个往上跳地修改,反正每个点只能被留下来一次,只要跳到了已经留过的点直接结束就行了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=1e6+10; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 int eg[maxn*2][2],egh[maxn],ect; 16 int fa[maxn][21],dep[maxn]; 17 int N,K; 18 bool flag[maxn]; 19 20 inline void adeg(int a,int b){ 21 eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect; 22 } 23 24 void dfs(int x){ 25 for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++) 26 fa[x][i+1]=fa[fa[x][i]][i]; 27 for(int i=egh[x];i;i=eg[i][1]){ 28 int b=eg[i][0];if(b==fa[x][0]) continue; 29 fa[b][0]=x; 30 dep[b]=dep[x]+1;dfs(b); 31 } 32 } 33 34 int main(){ 35 //freopen("","r",stdin); 36 int i; 37 N=rd(),K=rd(); 38 for(i=1;i<N;i++){ 39 int a=rd(),b=rd(); 40 adeg(a,b);adeg(b,a); 41 } 42 dep[N]=1;dfs(N); 43 K=N-K-1; 44 flag[N]=1; 45 for(i=N-1;i;i--){ 46 int x=i,n=0; 47 if(flag[i]) continue; 48 for(int j=log2(dep[x]);j>=0;j--){ 49 if(fa[x][j]&&!flag[fa[x][j]]) 50 n+=1<<j,x=fa[x][j]; 51 }n++; 52 if(n<=K){ 53 K-=n; 54 int x=i; 55 while(!flag[x]) flag[x]=1,x=fa[x][0]; 56 } 57 } 58 for(i=1;i<=N;i++) if(!flag[i]) printf("%d ",i); 59 return 0; 60 }