Submission #768940

#TimeUsernameProblemLanguageResultExecution timeMemory
768940APROHACKWiring (IOI17_wiring)C++14
100 / 100
91 ms36892 KiB
#include "wiring.h" #include <bits/stdc++.h> #define pb push_back #define pos first #define color second #define ll long long using namespace std; vector<pair<ll, bool> >nodes; ll distNext[200001]; // Distancia de este nodo con el siguiente de otro color ll distanciaAcum[200005]; // distancia acumulada si tomo desde i y lo uno con el siguiente del otro color int siguiente[200005]; // siguiente del otro color int nm; ll mem[200005]; ll toPut[200005]; struct segTree{ ll minimo, lazy; int dd, ht, mid; segTree *L, *R; segTree(int l, int r){ dd = l, ht = r; mid = (dd + ht)/2; lazy = 0; minimo = 0; if(l == r){ minimo = toPut[dd]; }else{ L = new segTree(l, mid); R = new segTree(mid+1, r); minimo = min(L->minimo, R->minimo); } } void propagate(){ L->lazy += lazy; R->lazy += lazy; if(L->minimo != LLONG_MAX)L->minimo += lazy; if(R->minimo != LLONG_MAX)R->minimo += lazy; //L->minimo += lazy; //R->minimo += lazy; lazy = 0; } void update(int l, int r, ll value){ if(l == dd and r == ht){ lazy += value; if(minimo != LLONG_MAX)minimo += value; return ; } propagate(); if(r <= mid){ L->update(l, r, value); }else if(l > mid){ R->update(l, r, value); }else{ L->update(l, mid, value); R->update(mid+1, r, value); } minimo = min(L->minimo, R->minimo); } ll query(int l, int r){ //cout << dd << " " << ht << " " << "query :" << l << " " << r << " " << minimo << endl; if(dd == l and r == ht)return minimo; propagate(); if( r <= mid)return L->query(l, r); else if( mid < l)return R->query(l, r); else return min(L->query(l, mid), R->query(mid+1, r)); } }; ll dp(int node){ } long long min_total_length(std::vector<int> r, std::vector<int> b) { memset(mem, -1, sizeof mem); int ir = r.size() -1, ib = 0; ll ans = 0; nm = r.size() + b.size(); for(auto i : r)nodes.pb({i, 0}); for(auto i : b)nodes.pb({i, 1}); sort(nodes.begin(), nodes.end()); ll last0 = -1, last1 = -1; int ultimo0 = -1, ultimo1 = -1; for(int i = nm-1 ; i >= 0 ; i --){ if(nodes[i].color == 0){ //cout << 0 << " "; if(last1-nodes[i].pos < 0){ distNext[i] = -1; }else{ distNext[i] = last1-nodes[i].pos; } last0 = nodes[i].pos; ultimo0 = i; siguiente[i] = ultimo1; }else{ //cout << 1 << " "; if(last0-nodes[i].pos < 0){ distNext[i] = -1; }else{ distNext[i] = last0-nodes[i].pos; } last1 = nodes[i].pos; ultimo1 = i; siguiente[i] = ultimo0; } } ll distCum[2]; distCum[0] = 0; distCum[1] = 0; for(int i = nm-1 ; i >= 0 ; i --){ if(distNext[i] != -1){ distCum[nodes[i].color] += distNext[i]; distanciaAcum[i] = distCum[nodes[i].color]; }else distanciaAcum[i] = -1; if(nodes[i].color == 0)distCum[1] = 0; else distCum[0] = 0; } bool currentColor = nodes[nm-1].color; int cuenta = 0, otraCuenta = 0; int idx = nm-1; mem[nm] = 0; for(; idx>= 0 ; idx --){ if(nodes[idx].color != currentColor)break; cuenta ++; mem[idx] = LLONG_MAX; } for(; idx >= 0 ;){ currentColor = nodes[idx].color; otraCuenta = 1; toPut[0] = 0; ll acum = 0; for(int i = 1 ; i <= cuenta ; i ++){ // agarrando i toPut[i] = acum; //if(mem[idx+i+1] == LLONG_MAX)toPut[i] = ((ll)INT_MAX) * 10000; /// caution if(min(mem[idx+i+1], mem[idx+i]) == LLONG_MAX)toPut[i] = LLONG_MAX; else toPut[i] += nodes[idx+i].pos-nodes[idx].pos + min(mem[idx+i+1], mem[idx+i]); acum += nodes[idx+i].pos-nodes[idx].pos; //cout << "tt " << i << " " << toPut[i] << endl; } segTree *currentState = new segTree(1, cuenta); //cout << "FROM " << idx << endl; //for(int i = 1 ; i <= cuenta ; i ++)cout << " taking " << i << ": " << currentState->query(i, i) <<endl; mem[idx] = currentState->query(1, cuenta); //cout << "ans for " << idx << " = " << mem[idx] << endl; idx--; while(nodes[idx].color == currentColor){ otraCuenta ++ ; currentState->update(1, min(otraCuenta-1, cuenta), nodes[siguiente[idx]].pos - nodes[idx].pos); if(min(otraCuenta-1, cuenta) + 1 <= cuenta){ currentState->update(min(otraCuenta-1, cuenta) + 1, cuenta, nodes[siguiente[idx]-1].pos - nodes[idx].pos); } //cout << "FROM " << idx << endl; //for(int i = 1 ; i <= cuenta ; i ++)cout << " taking " << i << ": " << currentState->query(i, i) <<endl; mem[idx] = currentState->query(1, cuenta); //cout << "ans for " << idx << " = " << mem[idx] << endl; idx--; } cuenta = otraCuenta; } return mem[0]; }

Compilation message (stderr)

wiring.cpp: In function 'long long int dp(int)':
wiring.cpp:74:1: warning: no return statement in function returning non-void [-Wreturn-type]
   74 | }
      | ^
wiring.cpp: In function 'long long int min_total_length(std::vector<int>, std::vector<int>)':
wiring.cpp:78:6: warning: unused variable 'ir' [-Wunused-variable]
   78 |  int ir = r.size() -1, ib = 0;
      |      ^~
wiring.cpp:78:24: warning: unused variable 'ib' [-Wunused-variable]
   78 |  int ir = r.size() -1, ib = 0;
      |                        ^~
wiring.cpp:79:5: warning: unused variable 'ans' [-Wunused-variable]
   79 |  ll ans = 0;
      |     ^~~
#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...