Submission #1352258

#TimeUsernameProblemLanguageResultExecution timeMemory
1352258cig32Voltage 2 (JOI26_voltage)C++20
100 / 100
51 ms968 KiB
#include "voltage.h"
#include "bits/stdc++.h"
#define vi vector<int>
#define pb push_back
#define sz(x) (int) (x).size()
#define pii pair<int, int>
using namespace std;
/*
-1: fst larger
0: same
1: snd larger
*/

int query_wrap(vi x, vi y) {
  int q = query(x, y);
  // cout << "? ";
  // cout << "[";
  // for (int z: x) cout << z;
  // cout << "] [";
  // for (int z: y) cout << z;
  // cout << "] = " << q << "\n";
  return q;
}

int N_;

bool solve(int N, int M) {
  N_ = N;
  vi prv(N, 0);
  int deadend[N];
  for (int i=0; i<N; i++) {
    vi all(N, 0);
    all[i] = 1;
    vi real(N, 0);
    if (query_wrap(real, all) == 0) deadend[i] = 1;
    else deadend[i] = 0;
  }
  bool unsure[N];
  queue<int> q;
  for (int i=0; i<N; i++) {
    if (!deadend[i]) {
      unsure[i] = 1;
    }
    else {
      q.push(i);
      unsure[i] = 0;
    }
  } 
  vector<pii> edges;

  vi adj[N];
  bool vis[N];
  for (int i=0; i<N; i++) vis[i] = 0;
  while (sz(q)) {
    int f = q.front();
    q.pop();
    vis[f] = 1;
    // cout << "visited "  << f << "\n";
    vi allunsure;
    for (int i=0; i<N; i++) if (unsure[i]) allunsure.pb(i);
    if (!sz(allunsure)) break;
    vi fr;
    // cout << "unsure: ";
    // for (int x: allunsure) cout << x << " ";
    // cout << "\n";
    while (1) {
      int lb = 0, rb = sz(allunsure);
      while (lb < rb) {
        int mid = (lb + rb) >> 1;
        vi on(N), off(N);
        for (int i=0; i<=mid; i++) on[allunsure[i]] = off[allunsure[i]] = 1;
        for (int i=0; i<N; i++) if (vis[i]) on[i] = off[i] = 1;
        off[f] = 0, on[f] = 1;
        if (query_wrap(off, on) == 0) lb = mid + 1;
        else rb = mid;
      }
      if (lb == sz(allunsure)) break;
      fr.pb(allunsure[lb]);
      for (int i=0; i<=lb; i++) allunsure.erase(allunsure.begin());
    }
    for (int x: fr) {
      vi off(N, 0);
      for (int i=0; i<N; i++) {
        if (vis[i]) off[i] = 1;
      }
      vi on;
      on = off;
      on[x] = 1;

      // cout << "found " << x << " -> " << f << "\n";
      edges.pb({x, f});
      adj[x].pb(f);
      if (query_wrap(on, off) == 0) {
        q.push(x);
        unsure[x] = 0;
        // cout << "mark " << x << " as done\n";
      }
      
    }
  }

  if (sz(edges) != M) return false;
  for (auto [u, v] : edges) answer(u, v);
  return true;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...