Submission #604813

#TimeUsernameProblemLanguageResultExecution timeMemory
604813MadokaMagicaFanICC (CEOI16_icc)C++14
100 / 100
147 ms636 KiB
#include "bits/stdc++.h" #ifndef ONPC #include "icc.h" #endif using namespace std; using ll = long long; using vi = vector<int>; using pi = pair<int, int>; #define forn(i,n) for(int i = 0; i < n; ++i) #define forr(i,n) for(int i = n-1; i >= 0; --i) #define forbe(i,b,e) for(int i = b; i < e; ++i) #define all(v) (v).begin(),(v).end() #define sort(v) sort(all(v)) #define sz(v) ((int)(v).size()) #define endl '\n' #define pb push_back #define f first #define s second //#define ONPC const int N = 100; int p[N]; int n; #ifdef ONPC int query(int size_a, int size_b, int *a, int *b); void setRoad(int a, int b); #endif int getp(int x) { return p[x] = (x == p[x]) ? x : getp(p[x]); } int uni(int a, int b) { a = getp(a); b = getp(b); p[a] = b; return(a != b); } int ask(bool par, vi va, vi vb) { forn(i, sz(va)) { if (getp(va[i]) == va[i] && par) { forn(j, n) { if (va[i] == j) continue; if (getp(j) == va[i]) va.pb(j); } } } forn(i, sz(vb)) { if (getp(vb[i]) == vb[i] && par) { forn(j, n) { if (vb[i] == j) continue; if (getp(j) == vb[i]) vb.pb(j); // if (getp(j) == vb[i]) cout << "SPL " << j << endl; } } } int sa, sb; sa = sz(va); sb = sz(vb); int a[N]; int b[N]; forn(i, sz(va)) a[i] = va[i] + 1; forn(i, sz(vb)) b[i] = vb[i] + 1; return query(sa, sb, a, b); } vi conc(vi a, vi b) { if (sz(a) < sz(b)) swap(a,b); vi c = a; for(int x : b) c.pb(x); return c; } struct tr { vi vl; vi vr; vi a; int n; tr(vi& _a) { a = _a; n = sz(a); vl.resize(4*n, -1); vr.resize(4*n, -1); build(1, 0, n-1); } void build(int i, int l, int r) { // cout << i << ' ' << l << ' ' << r << endl; int mid = (l+r)>>1; vl[i] = l; vr[i] = r; if (l == r) return; build(i<<1, l, mid); build(i<<1|1, mid+1, r); } vi get(int i) { if (vl[i] == vr[i]) return {a[vl[i]]}; return conc(get(i<<1) , get(i<<1|1)); } pi getc(int i) { if (vl[i<<1] == -1 || vl[i<<1|1] == -1) return {-1,-1}; return {i<<1, i<<1|1}; } }; void run (int _n) { n = _n; forn(i, n) p[i] = i; forn(j, n-1) { vi vals; vi par, oldpar; vi ka, kb; forn(i, n) if (i == getp(i)) vals.pb(i); tr x(vals); par.pb(1); // cout << "SZ: " << sz(vals) << endl; ka = x.get(2); kb = x.get(3); // cout << sz(ka) << ' ' << sz(kb) << endl; int k = ask(1, ka, kb); while (!k) { oldpar = par; par.clear(); ka.clear(); kb.clear(); // cout << "OLDPAR: "; for(int i : oldpar) { // cout << i << ' '; if (x.getc(i<<1).f != -1) par.pb(i<<1); if (x.getc(i<<1|1).f != -1) par.pb(i<<1|1); } // cout << endl; // cout << "Par: "; assert(sz(par)); for(int i : par) { // cout << i << ' '; // TODO optimize ka = conc(ka,x.get(i<<1)); kb = conc(kb,x.get(i<<1|1)); } // cout << endl; k = ask(1, ka, kb); } // cout << "Stuff" << endl; vi ta, tb; forn(i, sz(ka)) { if (getp(ka[i]) == ka[i]) { forn(j, n) { if (ka[i] == j) continue; if (getp(j) == ka[i]) ka.pb(j); } } } forn(i, sz(kb)) { if (getp(kb[i]) == kb[i]) { forn(j, n) { if (kb[i] == j) continue; if (getp(j) == kb[i]) kb.pb(j); } } } ta = ka; tb = kb; int l = 0; int r = sz(tb); while(l < r-1) { kb.clear(); int mid = (l+r)>>1; forbe(i, l, mid) kb.pb(tb[i]); if (ask(0,ka,kb)) r = mid; else l = mid; } int n1, n2; n1 = tb[l]; kb = {n1}; l = 0; r = sz(ka); while(l < r-1) { ka.clear(); int mid = (l+r)>>1; forbe(i, l, mid) ka.pb(ta[i]); if (ask(0,ka,kb)) r = mid; else l = mid; } n2 = ta[l]; // cout << n1+1 << ' ' << n2+1 << endl; setRoad(n1+1, n2+1); uni(n1,n2); } // cout << n << endl; } #ifdef ONPC int rp[N]; pi rd[N]; int cnt = 1; set<pi> edgs; int rgtp(int x) {return rp[x] = (rp[x] == x) ? x : rp[x]; } void setRoad(int a, int b) { if (a > b) swap(a,b); if (a == rd[cnt-1].f +1 && b == rd[cnt-1].s+1) { cout << "OK\n"; } else { cout << "NO\n"; exit(1); } if (cnt < n-1) { edgs.insert(rd[cnt]); // p[rgtp(rd[cnt].f)] = rd[cnt].s; ++cnt; } } int query(int size_a, int size_b, int *a, int *b) { // cout << "1: "; // forn(i, size_a) cout << a[i] << ' '; // cout << endl; // cout << "2: "; // forn(i, size_b) cout << b[i] << ' '; // cout << endl; forn(i, size_a) --a[i]; forn(i, size_b) --b[i]; // cout << 'T' << endl; forn(i, size_a) assert(a[i]+1 <= n); forn(i, size_b) assert(b[i]+1 <= n); forn(i, size_a) assert(a[i]+1 > 0); forn(i, size_b) assert(b[i]+1 > 0); forn(i, size_a) forn(j, size_b) assert(a[i] != b[j]); forn(i, size_a) { forn(j, size_b) { if (edgs.count({a[i], b[j]}) || edgs.count({b[j], a[i]})) return 1; } } // cout << 'F' << endl; // int x; // cin >> x; return 0; } void solve() { int n; cin >> n; forn(i,n) rp[i] = i; forn(i, n-1) cin >> rd[i].f >> rd[i].s; forn(i, n-1) --rd[i].f, --rd[i].s; forn(i, n-1) if (rd[i].f > rd[i].s) swap(rd[i].f, rd[i].s); edgs.insert(rd[0]); rp[rd[0].f] = rd[0].s; run(n); } int32_t main(int argc, char** argv) { if (argc > 1) freopen(argv[1],"r", stdin); solve(); } #endif
#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...