Codeforces Round #480 (Div. 2) E. The Number Games (Sparse Table + greedy)

题目链接

E. The Number Games

分析

题目是比较好的题

首先应该想到贪心的策略,对于 i 来说他爱的贡献是指数的即 2 i , 那么,我们可以这样想,尽量保留最大的 i , 而且答案要求是一个联通图,因此我们会保留 i 到树根路劲上所有节点。

for i = n-1 to 1,判断i是否能保留(ST 表计算他与当前答案子图的距离),

总结

  1. 删除叶子节点贪心算法有问题 WA7
  2. CF 对java 太不友好,dfs尽然爆内存
  3. 论缓存的重要性,将 ST表par[MAX_PAR][n] 能够利用cache 从而让我在 2995ms A 掉….

这里写图片描述

java code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;




public class Main {
    public static final int INF = 0x3f3f3f3f;
    public static final long INF64 = Long.MAX_VALUE/2;
    public static final int MAXN = 1000_000+5;
    public static final int MAX_PAR = 21;
    public static InputReader in = new InputReader(System.in);
    public static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
    public static int n,retain;
    public static int[][] par = new int[MAX_PAR][MAXN];
    public static boolean[] vis = new boolean[MAXN];
    @SuppressWarnings("unchecked")
    public static ArrayList<Integer>[] G = new ArrayList[MAXN];
    public static void main(String[] args) {
        n = in.nextInt();
        retain = n - in.nextInt();
        for(int i=1 ; i<=n ; ++i)G[i] = new ArrayList<>();
        for(int i=1 ; i<n ; ++i){
            int a = in.nextInt();
            int b = in.nextInt();
            G[a].add(b);
            G[b].add(a);
        }
        solve();
        for(int i=1 ; i<=n ; ++i)
            if(!vis[i])
                out.print(i+" ");
        out.flush();
    }
    public static void solve() {
        findPar();
        Arrays.fill(vis, false);
        int num =1;
        vis[n]=true;
        vis[0] = true;
        for(int i=n-1; i>0 ; --i){
            if(vis[i])continue;
            int itr =i;
            int dis =1;
            for(int k=MAX_PAR-1 ; k>=0 ; k--)
                if(!vis[par[k][itr]]){
                    dis += 1 <<k;
                    itr = par[k][itr];
                }
//          System.out.println(i +" "+ dis);
            itr =i;
            if(dis + num <= retain){
                num += dis;
                while (!vis[itr]) {
                    vis[itr] = true;
                    itr = par[0][itr];
                }

                if(num==retain)break;
            }
        }
    }
    private static void findPar() {
        Arrays.fill(vis, false);
        Queue<Integer> Q = new LinkedList<>();
        Q.add(n);
        vis[n] = true;
        par[0][n] =0;
        for(int i=1 ; i<MAX_PAR ; ++i)par[i][n]=0;
        while (!Q.isEmpty()) {
            int p = Q.remove();
            for(Integer v: G[p]){
                if(vis[v])continue;
                vis[v] = true;
                Q.add(v);
                par[0][v] =p;
            }
        }
        for(int k=1 ; k<MAX_PAR ; ++k)
            for(int i=1 ; i<=n ; ++i)
                par[k][i] = par[k-1][par[k-1][i]];
    }
}

class InputReader{
    private final static int BUF_SZ = 32768;
    BufferedReader in;
    StringTokenizer tokenizer;
    public InputReader(InputStream in) {
        super();
        this.in = new BufferedReader(new InputStreamReader(in),BUF_SZ);
        tokenizer = new StringTokenizer("");
    }
    private String next() {
        while (!tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(in.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }
    public int nextInt() {
        return Integer.parseInt(next());
    }
    public long nextLong() {
        return Long.parseLong(next());
    }
    public double nextDouble() {
        return Double.parseDouble(next());
    }
    public BigInteger nextBigInteger() {
        return new BigInteger(next());
    }
}

猜你喜欢

转载自blog.csdn.net/dylan_frank/article/details/80356841