【CodeCraft-19 and Codeforces Round #537 (Div. 2) C】Creative Snap
阿新 • • 發佈:2019-02-09
snap 。。 我們 math except iter right row else
【鏈接】 我是鏈接,點我呀:)
【題意】
橫坐標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,mid]和[mid+1,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,r = k,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()); } } }
【CodeCraft-19 and Codeforces Round #537 (Div. 2) C】Creative Snap