Submission #1093892

#TimeUsernameProblemLanguageResultExecution timeMemory
1093892azberjibiouSimurgh (IOI17_simurgh)C++17
13 / 100
125 ms6100 KiB
#include "simurgh.h" #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include <bits/stdc++.h> #define all(v) v.begin(), v.end() #define pb push_back #define lb lower_bound #define gibon ios::sync_with_stdio(false); cin.tie(0); #define fi first #define se second #define pii pair<int, int> #define pll pair<ll, ll> typedef long long ll; using namespace std; const int mxN=505; const int mxM=10000; const int mxK=60; const ll INF=1e18; struct uf{ int p[mxN]; void init(int n){for(int i=0;i<n;i++) p[i]=i;} int fp(int a){return p[a]==a ? a : p[a]=fp(p[a]);} void mrg(int a, int b){p[fp(a)]=fp(b);} }; int N; vector <int> v[mxN]; vector <pii> E; int num[mxN][mxN]; int gold[mxN][mxN]; //dfs bool Chk[mxN]; int dep[mxN], par[mxN]; vector <int> tree; void init(){ for(int i=0;i<mxN;i++) v[i].clear(); E.clear(); for(int i=0;i<mxN;i++) for(int j=0;j<mxN;j++) num[i][j]=-1, gold[i][j]=-1; for(int i=0;i<mxN;i++) Chk[i]=false, dep[i]=0, par[i]=0; tree.clear(); } void dfs(int now){ Chk[now]=true; for(int nxt : v[now]) if(!Chk[nxt]){ dep[nxt]=dep[now]+1; par[nxt]=now; tree.push_back(num[nxt][now]); dfs(nxt); } } uf U_qry; int make_query(vector <int> qry, bool proc){ // qry does not have a cycle!, proc: remove value of edges out of qry vector <int> res=qry; U_qry.init(N); for(int x : qry) U_qry.mrg(E[x].fi, E[x].se); for(int x : tree){ auto [now1, now2]=E[x]; if(U_qry.fp(now1)!=U_qry.fp(now2)){ res.push_back(x); U_qry.mrg(now1, now2); } } int val=count_common_roads(res); if(proc){ for(int i=qry.size();i<res.size();i++){ auto [now1, now2]=E[res[i]]; if(gold[now1][now2]==1) val--; } } return val; } vector <int> minu(vector <int> gph, int x){ vector <int> res; for(int y : gph) if(y!=x) res.push_back(y); return res; } void check_cycle(vector <int> cyc){ vector <int> qres(cyc.size(), -1); int know=-1; for(int x : cyc) if(gold[E[x].fi][E[x].se]!=-1) know=x; int tot=-1; if(know!=-1){ tot=make_query(minu(cyc, know), false)+gold[E[know].fi][E[know].se]; } for(int i=0;i<cyc.size();i++){ auto [now1, now2]=E[cyc[i]]; if(gold[now1][now2]==-1) qres[i]=make_query(minu(cyc, cyc[i]), false); } if(know==-1){ int sum=0; for(int i=0;i<cyc.size();i++) sum+=qres[i]; sum/=cyc.size(); tot=sum+1; } for(int i=0;i<cyc.size();i++){ auto [now1, now2]=E[cyc[i]]; if(gold[now1][now2]==-1){ if(qres[i]==tot) gold[now1][now2]=gold[now2][now1]=0; else gold[now1][now2]=gold[now2][now1]=1; } } } void make_spanning_tree(){ dfs(0); sort(all(tree), [](int a, int b){return min(dep[E[a].fi], dep[E[a].se])>min(dep[E[b].fi], dep[E[b].se]);}); for(int ednum : tree){ auto [now1, now2]=E[ednum]; if(dep[now1]>dep[now2]) swap(now1, now2); if(gold[now1][now2]!=-1) continue; int up=-1; for(int x : v[now2]) if(dep[x]<dep[now1]){ if(up==-1 || dep[x]<dep[up]) up=x; } if(up==-1){ gold[now1][now2]=gold[now2][now1]=1; continue; } vector <int> cyc; int pnt=now2; while(pnt!=up){ cyc.push_back(num[pnt][par[pnt]]); pnt=par[pnt]; } cyc.push_back(num[now2][up]); check_cycle(cyc); } } vector <int> rng(vector <int> s, pii lr){ vector <int> res; for(int i=lr.fi;i<=lr.se;i++) res.push_back(s[i]); return res; } void find_gold(){ for(int i=0;i<N;i++){ vector <int> ct; for(int j=i+1;j<N;j++){ if(num[i][j]!=-1 && gold[i][j]==-1) ct.push_back(num[i][j]); } while(ct.size() && make_query(ct, true)!=0){ int s=0, e=ct.size()-1; while(s!=e){ int mid=(s+e)/2; if(make_query(rng(ct, pii(s, mid)), true)==0) s=mid+1; else e=mid; } auto [now1, now2]=E[ct[s]]; gold[now1][now2]=gold[now2][now1]=1; ct=minu(ct, ct[s]); } } } std::vector<int> find_roads(int n, std::vector<int> a, std::vector<int> b) { N=n; init(); for(int i=0;i<a.size();i++){ int t1=a[i], t2=b[i]; v[t1].push_back(t2); v[t2].push_back(t1); E.emplace_back(t1, t2); num[t1][t2]=num[t2][t1]=i; } make_spanning_tree(); find_gold(); vector<int> r; for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) if(gold[i][j]==1) r.push_back(num[i][j]); return r; }

Compilation message (stderr)

simurgh.cpp: In function 'int make_query(std::vector<int>, bool)':
simurgh.cpp:64:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   64 |         for(int i=qry.size();i<res.size();i++){
      |                              ~^~~~~~~~~~~
simurgh.cpp: In function 'void check_cycle(std::vector<int>)':
simurgh.cpp:84:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   84 |     for(int i=0;i<cyc.size();i++){
      |                 ~^~~~~~~~~~~
simurgh.cpp:90:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   90 |         for(int i=0;i<cyc.size();i++) sum+=qres[i];
      |                     ~^~~~~~~~~~~
simurgh.cpp:94:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   94 |     for(int i=0;i<cyc.size();i++){
      |                 ~^~~~~~~~~~~
simurgh.cpp: In function 'std::vector<int> find_roads(int, std::vector<int>, std::vector<int>)':
simurgh.cpp:154:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  154 |     for(int i=0;i<a.size();i++){
      |                 ~^~~~~~~~~
#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...