微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【CodeCraft-19 and Codeforces Round #537 (Div. 2) C】Creative Snap

链接 我是链接,点我呀:)
【题意】


横坐标1..2^n对应着2^n个复仇者的基地,上面有k个复仇者(位置依次给出)。
你是灭霸你要用以下方法消灭这k个复仇者:
一开始你获取整个区间[1..2^n]
假设你当前获取的区间为[l,r]
mid = (l+r)/2
那么你每次有两种选择
1.将整个区间全都毁掉,如果这个区间里没有复仇者,那么花费为A,否则花费为B复仇者个数区间长度
2.将区间分为[l,mid]和[mid+1,r]分开毁掉(即分别获取[l,r]这两个区间,然后累加递归处理后的花费)
问你最小花费是多少

【题解】


如果2^n比较大的话,k个复仇者其实所占据的区间会非常少
也就是说有很多区间都是空着的。。
而空着的区间其实就没有必要用第二种选择了,因为显然直接返回A是最好的
所以我们只需要模拟题目说的方法就好。
只需要用两个二分查找获取当前区间里面有多少个复仇者就好
如果没有复仇者了就直接返回A,否则模拟题目描述就ok
(同一个基地可能有多个复仇者).

代码

import java.io.*;
import java.util.*;

public class Main {
    
    final static int N = (int)1e5;
    static InputReader in;
    static PrintWriter out;
    static int n,k,A,B,a[],r;
    
    static int leftmorethan(int x) {
        int l = 1,r = k,temp=-1;
        while (l<=r) {
            int mid = (l+r)>>1;
            if (x<=a[mid]) {
                temp = mid;
                r = mid - 1;
            }else {
                l = mid + 1;
            }
        }
        return temp;
    }
    
    static int rightlessthan(int x) {
        int l = 1,temp = -1;
        while (l<=r) {
            int mid = (l+r)>>1;
            if (x>=a[mid]) {
                temp = mid;
                l = mid + 1;
            }else {
                r = mid-1;
            }
        }
        return temp;
    }
    
    
    static long dfs(int l,int r) {
        int L = leftmorethan(l);
        int R = rightlessthan(r);
        boolean ok = true;
        if (L==-1 || R==-1) ok = false;
        if (L>R) ok = false;
        if (!ok) return 1l*A;
        
        if (l==r) return 1l*B*(R-L+1);
        
        int mid = (l+r)>>1;
        long ans;
        //select all
        ans = 1l*B*(R-L+1)*(r-l+1);
        
        //divede
        ans = Math.min(ans,dfs(l,mid)+dfs(mid+1,r));
        return ans;
    }
        
    public static void main(String[] args) throws IOException{
        in = new InputReader();
        out = new PrintWriter(System.out);
        
        //code start from here
        a = new int[N+10];
        n = in.nextInt();k = in.nextInt();A = in.nextInt();B = in.nextInt();
        for (int i = 1; i <= k;i++) a[i] = in.nextInt();
        r = 1;
        for (int i = 1;i <= n;i++) r = r*2;
        Arrays.sort(a,1,k+1);
        out.print(dfs(1,r));
        out.close();
    }

    static class InputReader{
        public BufferedReader br;
        public StringTokenizer tokenizer;
        
        public InputReader() {
            br = new BufferedReader(new InputStreamReader(system.in));
            tokenizer = null;
        }
        
        public String next(){
            while (tokenizer==null || !tokenizer.hasMoretokens()) {
                try {
                tokenizer = new StringTokenizer(br.readLine());
                }catch(IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
        
        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。