Submission #381031

#TimeUsernameProblemLanguageResultExecution timeMemory
381031ponytailRace (IOI11_race)C++17
0 / 100
10 ms16108 KiB
#include "bits/stdc++.h" using namespace std; #ifdef ONLINE_JUDGE #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST; #endif #define int long long #define double long double #define mp make_pair #define fi first #define se second #define pb push_back #define all(a) a.begin(),a.end() const int MOD = 1000000007; const int MOD2 = 998244353; const int BIG = 1197423052705914509LL; mt19937 rng((int) std::chrono::steady_clock::now().time_since_epoch().count()); const int MAXN = 2e5 + 10; const int NO_OPERATION = 69420420420LL; const int is_query = -BIG; struct line { int m, b; mutable function<const line*()> succ; bool operator<(const line& rhs) const { if (rhs.b != is_query) return m < rhs.m; const line* s = succ(); if (!s) return 0; int x = rhs.m; return b - s->b < (s->m - m) * x; } }; struct dynamic_hull : public multiset<line> { const int inf = BIG; bool bad(iterator y) { auto z = next(y); if (y == begin()) { if (z == end()) return 0; return y->m == z->m && y->b <= z->b; } auto x = prev(y); if (z == end()) return y->m == x->m && y->b <= x->b; int v1 = (x->b - y->b); if (y->m == x->m) v1 = x->b > y->b ? inf : -inf; else v1 /= (y->m - x->m); int v2 = (y->b - z->b); if (z->m == y->m) v2 = y->b > z->b ? inf : -inf; else v2 /= (z->m - y->m); return v1 >= v2; } void insert_line(int m, int b) { auto y = insert({m,b}); y->succ = [=] { return next(y) == end() ? 0 : &*next(y); }; if (bad(y)) { erase(y); return; } while (next(y) != end() && bad(next(y))) erase(next(y)); while (y != begin() && bad(prev(y))) erase(prev(y)); } int eval(int x) { auto l = *lower_bound((line) { x, is_query }); return l.m * x + l.b; } }; struct auxiliary_tree{ int n; vector<int>ori[MAXN]; vector<int>storelatest; int tin[MAXN], tout[MAXN], dep[MAXN], cor[MAXN]; bool imp[MAXN]; int run=0; vector<int>euler; vector<vector<pair<int,int> > >lca_table; int lef[MAXN], rig[MAXN]; void dfs(int node,int prev,int de){ dep[node]=de; tin[node]=++run; cor[tin[node]]=node; euler.pb(node); for(int i=0;i<ori[node].size();i++){ if(ori[node][i]!=prev){ dfs(ori[node][i],node,de+1); euler.pb(node); } } tout[node]=++run; } void find_all_lcas(){ int k=log2(2*n-1); lca_table.resize(k+1); for(int i=0;i<k+1;i++){ lca_table[i].resize(2*n-1); } for(int i=0;i<2*n-1;i++){ lca_table[0][i]=mp(dep[euler[i]],euler[i]); } for(int i=1;i<=k;i++){ for(int j=0;j<2*n-1;j++){ if(j+(1<<(i-1))>=2*n-1)continue; if(lca_table[i-1][j].fi<lca_table[i-1][j+(1<<(i-1))].fi){ lca_table[i][j].fi=lca_table[i-1][j].fi; lca_table[i][j].se=lca_table[i-1][j].se; } else{ lca_table[i][j].fi=lca_table[i-1][j+(1<<(i-1))].fi; lca_table[i][j].se=lca_table[i-1][j+(1<<(i-1))].se; } } } for(int i=0;i<MAXN;i++) lef[i]=-1; for(int i=0;i<2*n-1;i++){ if(lef[euler[i]]==-1){ lef[euler[i]]=i; } rig[euler[i]]=i; } } bool isParent(int u,int v){ return tin[u]<tin[v] && tout[v]<tout[u]; } public: vector<int>adj[MAXN]; int root; int lcadep(int x,int y){ if(lef[x]>rig[y]){ swap(x,y); } int k=log2(rig[y]-lef[x]+1); return min(lca_table[k][lef[x]].fi,lca_table[k][rig[y]-(1<<k)+1].fi); } int lcaidx(int x,int y){ if(lef[x]>rig[y]){ swap(x,y); } int k=log2(rig[y]-lef[x]+1); if(lca_table[k][lef[x]].fi<lca_table[k][rig[y]-(1<<k)+1].fi){ return lca_table[k][lef[x]].se; } else{ return lca_table[k][rig[y]-(1<<k)+1].se; } } void base(int x,int rt,vector<int>y[]){ n=x; for(int i=1;i<=n;i++){ ori[i]=y[i]; } dfs(rt,-1,0); find_all_lcas(); } void build(vector<int>g){ for(int i=0;i<g.size();i++){ g[i]=tin[g[i]]; } sort(all(g)); for(int i=0;i<g.size();i++){ g[i]=cor[g[i]]; } int k=g.size(); for(int i=0;i<k-1;i++){ g.pb(lcaidx(g[i],g[i+1])); } for(int i=0;i<g.size();i++){ g[i]=tin[g[i]]; } sort(all(g)); for(int i=0;i<g.size();i++){ g[i]=cor[g[i]]; } g.erase(unique(all(g)),g.end()); for(int i=0;i<g.size();i++){ imp[g[i]]=1; storelatest.pb(g[i]); } stack<int>vert; vert.push(g[0]); for(int i=1;i<g.size();i++){ int u=g[i]; while(vert.size()>1 && isParent(vert.top(),u)==0){ int sto=vert.top(); vert.pop(); adj[vert.top()].pb(sto); } vert.push(u); } while(vert.size()>1){ int sto=vert.top(); vert.pop(); adj[vert.top()].pb(sto); } root=vert.top(); } void clear(){ for(int i=0;i<storelatest.size();i++){ imp[storelatest[i]]=0; adj[storelatest[i]].clear(); } storelatest.clear(); } }; struct custom_hash{ static uint64_t splitmix64(uint64_t x){ x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t a) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(a + FIXED_RANDOM); } template<class T> size_t operator()(T a) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); hash<T> x; return splitmix64(x(a) + FIXED_RANDOM); } template<class T, class H> size_t operator()(pair<T, H> a) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); hash<T> x; hash<H> y; return splitmix64(x(a.f) * 37 + y(a.s) + FIXED_RANDOM); } }; template<class T, class H>using umap=unordered_map<T,H,custom_hash>; int sz[MAXN], maxsz[MAXN], n, k; vector<pair<int,int> >adj[MAXN]; unordered_map<int,int> f[MAXN]; const int MAXK = 10000010; int exist[MAXK], exist2[MAXK]; int ans = 1e9; int whole_size; int number_of_operations = 0; int dfs0(int node,int prev){ sz[node]=1; number_of_operations++; for(pair<int,int>x:adj[node]){ if(x.se==-1)continue; if(x.fi==prev)continue; int d=dfs0(x.fi,node); sz[node]+=d; } return sz[node]; } int dfs(int node,int prev){ sz[node]=1; maxsz[node]=0; number_of_operations++; for(pair<int,int> x:adj[node]){ if(x.se==-1) continue; if(x.fi==prev) continue; int d=dfs(x.fi,node); sz[node]+=d; maxsz[node]=max(maxsz[node],d); } maxsz[node]=max(maxsz[node],whole_size-sz[node]); return sz[node]; } queue<int>ntv; vector<int>all; void wheewhoowhee(int node,int prev){ all.pb(node); for(pair<int,int>x:adj[node]){ if(x.se==-1)continue; if(x.fi==prev)continue; wheewhoowhee(x.fi,node); } } int divide(){ all.clear(); wheewhoowhee(ntv.front(),-1); for(int i:all){ sz[i]=0; maxsz[i]=1e9; number_of_operations++; } whole_size=dfs0(ntv.front(),-1); dfs(ntv.front(),-1); ntv.pop(); int centroid=0, e=1e9; for(int i:all){ if(e>maxsz[i]){ e=maxsz[i]; centroid=i; } } for(pair<int,int> x:adj[centroid]){ if(x.se==-1) continue; ntv.push(x.fi); } return centroid; } queue<int>used, used2, used3; void dfs2(int node,int prev,int cur,int dep){ // cout <<cur <<"\n"; if(cur>=1 && cur<MAXK && exist2[cur]==1e9){ // cout << "FUCK\n"; used.push(cur); used3.push(cur); } if(cur>=1 && cur<MAXK){ exist2[cur]=min(exist2[cur],dep); } for(pair<int,int>x:adj[node]){ if(x.se==-1) continue; if(x.fi==prev) continue; dfs2(x.fi,node,cur+x.se,dep+1); } } void conquer(int root){ while(used2.size()){ exist[used2.front()]=1e9; used2.pop(); } for(int i=0;i<adj[root].size();i++){ if(adj[root][i].se==-1) continue; int sto=adj[root][i].se; adj[root][i].se=-1; adj[adj[root][i].fi][f[adj[root][i].fi][root]].se=-1; dfs2(adj[root][i].fi,-1,sto,1); while(used3.size()){ // cout << "E "<<i<<" "<<used3.front()<<"\n"; if(k==used3.front()){ ans=min(ans,exist2[used3.front()]); } if(k-used3.front()>=1 && k-used3.front()<MAXK && exist[k-used3.front()]!=1e9){ // cout << "F "<<exist[k-used3.front()] << " " << exist2[used3.front()] << "\n"; ans=min(ans,exist[k-used3.front()]+exist2[used3.front()]); // cout << "G "<<ans << "\n"; } used3.pop(); } while(used.size()){ if(exist[used.front()]==1e9) used2.push(used.front()); exist[used.front()]=min(exist[used.front()],exist2[used.front()]); // cout << "exist "<<used.front()<<" "<<exist[used.front()]<<"\n"; exist2[used.front()]=1e9; used.pop(); } } } signed best_path(signed N,signed K,signed h[][2],signed l[]){ int n=N, k=K; for(int i=1;i<=n;i++) exist[i]=1e9, exist2[i]=1e9; for(int i=1;i<n;i++){ int u=h[i-1][0],v=h[i-1][1],w=l[i-1]; //cin >> u >> v >> w; u++, v++; int U=adj[u].size(); int V=adj[v].size(); f[u][v]=U; f[v][u]=V; adj[u].pb({v,w}); adj[v].pb({u,w}); } ntv.push(1); while(ntv.size()){ conquer(divide()); } return (ans==1e9 ? -1 : ans); }

Compilation message (stderr)

race.cpp: In member function 'void auxiliary_tree::dfs(long long int, long long int, long long int)':
race.cpp:79:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   79 |         for(int i=0;i<ori[node].size();i++){
      |                     ~^~~~~~~~~~~~~~~~~
race.cpp: In member function 'void auxiliary_tree::build(std::vector<long long int>)':
race.cpp:151:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  151 |         for(int i=0;i<g.size();i++){
      |                     ~^~~~~~~~~
race.cpp:155:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  155 |         for(int i=0;i<g.size();i++){
      |                     ~^~~~~~~~~
race.cpp:162:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  162 |         for(int i=0;i<g.size();i++){
      |                     ~^~~~~~~~~
race.cpp:166:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  166 |         for(int i=0;i<g.size();i++){
      |                     ~^~~~~~~~~
race.cpp:170:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  170 |         for(int i=0;i<g.size();i++){
      |                     ~^~~~~~~~~
race.cpp:176:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  176 |         for(int i=1;i<g.size();i++){
      |                     ~^~~~~~~~~
race.cpp: In member function 'void auxiliary_tree::clear()':
race.cpp:193:22: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  193 |         for(int i=0;i<storelatest.size();i++){
      |                     ~^~~~~~~~~~~~~~~~~~~
race.cpp: In function 'void conquer(long long int)':
race.cpp:313:18: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  313 |     for(int i=0;i<adj[root].size();i++){
      |                 ~^~~~~~~~~~~~~~~~~
race.cpp: In function 'int best_path(int, int, int (*)[2], int*)':
race.cpp:341:14: warning: unused variable 'k' [-Wunused-variable]
  341 |     int n=N, k=K;
      |              ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...