RUCP2016 Day3 D Complex Oracle - Complex Oracle -
問題
http://judge.u-aizu.ac.jp/onlinejudge/cdescription.jsp?cid=RitsCamp16Day3&pid=D
考察にめちゃくちゃ時間を奪われたので,もっと考察する時間を短縮させたい。
考察
は,
全体で番目の値より大きい値の数が分かれば,番目の値がこの数列の中で何番目に大きいのかが分かる。
それをN回繰り返せば元の数列が分かる。
解説:
http://www.slideshare.net/hcpc_hokudai/2016d-60984811
他の解説記事:
pekempeyさん
pekempey.hatenablog.com
kenkooooさん
セグメント木を使う方法があったっぽいけど,全く思いつかなかった...。セグメント木を使う問題に慣れて無さ過ぎた...
ソースコード
import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.Arrays; import java.util.NoSuchElementException; public class Main implements Runnable{ int N; int[] ans; long[] left,right; public long query(int l,int r){ if(l == 1){ if(left[r] == -1){ out.println("? " + l + " " + r); out.flush(); return left[r] = nextLong(); }else{ return left[r]; } }else{ if(right[l] == -1){ out.println("? " + l + " " + r); out.flush(); return right[l] = nextLong(); }else{ return right[l]; } } } public void solve() { N = nextInt(); ans = new int[N]; left = new long[N+1]; right = new long[N+1]; Arrays.fill(left, -1); Arrays.fill(right, -1); for(int i = 1;i <= N;i++){ int L = 0; int R = 0; if(i - 1 >= 1){ L = (int)(query(1,i) - query(1,i-1)); } if(i + 1 <= N){ R = (int)(query(i,N) - query(i+1,N)); R = (N - (i + 1) + 1) - R; } ans[i-1] = N - L - R; } out.print("!"); for(int i = 0;i < N;i++){ out.print(" " + ans[i]); } out.println(); } public static void main(String[] args) { new Thread(null,new Main(),"",32 * 1024 * 1024).start(); } /* Input */ private static final InputStream in = System.in; private static final PrintWriter out = new PrintWriter(System.out); private final byte[] buffer = new byte[2048]; private int p = 0; private int buflen = 0; private boolean hasNextByte() { if (p < buflen) return true; p = 0; try { buflen = in.read(buffer); } catch (IOException e) { e.printStackTrace(); } if (buflen <= 0) return false; return true; } public boolean hasNext() { while (hasNextByte() && !isPrint(buffer[p])) { p++; } return hasNextByte(); } private boolean isPrint(int ch) { if (ch >= '!' && ch <= '~') return true; return false; } private int nextByte() { if (!hasNextByte()) return -1; return buffer[p++]; } public String next() { if (!hasNext()) throw new NoSuchElementException(); StringBuilder sb = new StringBuilder(); int b = -1; while (isPrint((b = nextByte()))) { sb.appendCodePoint(b); } return sb.toString(); } public int nextInt() { return Integer.parseInt(next()); } public long nextLong() { return Long.parseLong(next()); } public double nextDouble() { return Double.parseDouble(next()); } @Override public void run() { out.flush(); new Main().solve(); out.close(); } }