Submission #51013

#TimeUsernameProblemLanguageResultExecution timeMemory
51013FLDutchmanSimurgh (IOI17_simurgh)C++14
100 / 100
318 ms30336 KiB
#include "simurgh.h" #include <bits/stdc++.h> using namespace std; #define FOR(i, l, r) for(int i = l; i < r; i++) #define pb push_back #define fst first #define snd second typedef vector<int> vi; typedef pair<int, int> ii; typedef vector<ii> vii; vi isGolden; // -1 = unknown; 0 = false; 1 = true vi par, parEdge, height; //Parent in dfs tree vi tree; // set of edges vi adj[510]; vi adjidx[510]; vii edges; //Edges: sorted by heigth in tree void buildTree(int n){ FOR(i, 0, adj[n].size()){ int k = adj[n][i]; if(height[k] == -1){ par[k] = n; parEdge[k] = adjidx[n][i]; tree.pb(parEdge[k]); height[k] = height[n]+1; buildTree(k); } } } int queryReplacement(int a, int b){ FOR(i, 0, tree.size()){ if(tree[i] == a) { tree[i] = b; int k = count_common_roads(tree); tree[i] = a; return k; } } } void detTree(){ int treecnt = count_common_roads(tree); FOR(i, 0, edges.size()){ auto e = edges[i]; if(par[e.fst] == e.snd) continue; int n = e.fst; bool allDet = true, allUndet = true; int p = 0; while(n != e.snd){ if(isGolden[parEdge[n]] == -1) allDet = false; if(isGolden[parEdge[n]] != -1) { p = parEdge[n]; allUndet = false; } n = par[n]; } if(allDet) { continue; } n = e.fst; if(allUndet){ bool dec = false, inc = false; while(n != e.snd){ int q = queryReplacement(parEdge[n], i); if(q < treecnt) {dec = true; isGolden[parEdge[n]] = 1;} if(q > treecnt) {inc = true; isGolden[parEdge[n]] = 0;} n = par[n]; } n = e.fst; if(inc) while(n != e.snd) {if(isGolden[parEdge[n]] == -1) isGolden[parEdge[n]] = 1; n = par[n];} else if(dec) while(n != e.snd) {if(isGolden[parEdge[n]] == -1) isGolden[parEdge[n]] = 0; n = par[n];} else while(n != e.snd) {isGolden[parEdge[n]] = 0; n = par[n];} } else { int k = queryReplacement(p, i); int v = k - treecnt + isGolden[p]; while(n != e.snd){ if(isGolden[parEdge[n]] == -1){ int t = queryReplacement(parEdge[n], i); isGolden[parEdge[n]] = treecnt + v - t; } n = par[n]; } } } for(int e : tree){ if(isGolden[e] == -1) isGolden[e] = 1; } } vi ufp; int find(int a) {return ufp[a] = ufp[a] == a ? a : find(ufp[a]);} void comb(int a, int b) {ufp[find(a)] = ufp[find(b)];} int queryForest(vi forest){ ufp.clear(); FOR(i, 0, tree.size()+1) ufp.pb(i); for(int e : forest){ comb(edges[e].fst, edges[e].snd); } int treeVal = 0; for(int e : tree){ if(find(edges[e].fst) != find(edges[e].snd)){ treeVal += isGolden[e]; forest.pb(e); comb(edges[e].fst, edges[e].snd); } } return count_common_roads(forest) - treeVal; } int queryInterval(int n, int lb, int rb){ vi forest; FOR(i, lb, rb){ if(isGolden[adjidx[n][i]] != 1) forest.pb(adjidx[n][i]); } return queryForest(forest); } vi find_roads(int n, vi u, vi v) { par.assign(n, -1); parEdge.assign(n, -1); height.assign(n, -1); isGolden.assign(u.size(), -1); FOR(i, 0, u.size()) { adj[u[i]].pb(v[i]); adj[v[i]].pb(u[i]); adjidx[u[i]].pb(i); adjidx[v[i]].pb(i); } par[0] = height[0] = 0; parEdge[0] = -1; buildTree(0); FOR(i, 0, u.size()) { if(height[u[i]] > height[v[i]]) edges.pb({u[i], v[i]}); else edges.pb({v[i], u[i]}); } detTree(); queue<int> q; vi outCount; FOR(i, 0, tree.size()+1){ outCount.pb(queryInterval(i, 0, adj[i].size())); if(outCount[i] == 1) q.push(i); } int c = 0; while(!q.empty()){ int k = q.front(); q.pop(); if(outCount[k] == 0) continue; int lb = 0, rb = adj[k].size(); while(lb+1 != rb){ int mb = (lb+rb)/2; if(queryInterval(k, lb, mb)) rb = mb; else lb = mb; } isGolden[adjidx[k][lb]] = 1; outCount[adj[k][lb]] --; outCount[k]--; if(outCount[adj[k][lb]] == 1) { q.push(adj[k][lb]);} } vi t; FOR(i, 0, isGolden.size()){ if(isGolden[i] == 1) t.pb(i); } return t; }

Compilation message (stderr)

simurgh.cpp: In function 'void buildTree(int)':
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:23:6:
  FOR(i, 0, adj[n].size()){
      ~~~~~~~~~~~~~~~~~~~               
simurgh.cpp:23:2: note: in expansion of macro 'FOR'
  FOR(i, 0, adj[n].size()){
  ^~~
simurgh.cpp: In function 'int queryReplacement(int, int)':
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:36:6:
  FOR(i, 0, tree.size()){
      ~~~~~~~~~~~~~~~~~                 
simurgh.cpp:36:2: note: in expansion of macro 'FOR'
  FOR(i, 0, tree.size()){
  ^~~
simurgh.cpp: In function 'void detTree()':
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:48:6:
  FOR(i, 0, edges.size()){
      ~~~~~~~~~~~~~~~~~~                
simurgh.cpp:48:2: note: in expansion of macro 'FOR'
  FOR(i, 0, edges.size()){
  ^~~
simurgh.cpp: In function 'int queryForest(vi)':
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:102:6:
  FOR(i, 0, tree.size()+1) ufp.pb(i);
      ~~~~~~~~~~~~~~~~~~~               
simurgh.cpp:102:2: note: in expansion of macro 'FOR'
  FOR(i, 0, tree.size()+1) ufp.pb(i);
  ^~~
simurgh.cpp: In function 'vi find_roads(int, vi, vi)':
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:130:6:
  FOR(i, 0, u.size()) {
      ~~~~~~~~~~~~~~                    
simurgh.cpp:130:2: note: in expansion of macro 'FOR'
  FOR(i, 0, u.size()) {
  ^~~
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:139:6:
  FOR(i, 0, u.size()) {
      ~~~~~~~~~~~~~~                    
simurgh.cpp:139:2: note: in expansion of macro 'FOR'
  FOR(i, 0, u.size()) {
  ^~~
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:147:6:
  FOR(i, 0, tree.size()+1){
      ~~~~~~~~~~~~~~~~~~~               
simurgh.cpp:147:2: note: in expansion of macro 'FOR'
  FOR(i, 0, tree.size()+1){
  ^~~
simurgh.cpp:5:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = l; i < r; i++)
simurgh.cpp:168:6:
  FOR(i, 0, isGolden.size()){
      ~~~~~~~~~~~~~~~~~~~~~             
simurgh.cpp:168:2: note: in expansion of macro 'FOR'
  FOR(i, 0, isGolden.size()){
  ^~~
simurgh.cpp:151:6: warning: unused variable 'c' [-Wunused-variable]
  int c = 0;
      ^
simurgh.cpp: In function 'int queryReplacement(int, int)':
simurgh.cpp:44:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
#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...