Submission #1189714

#TimeUsernameProblemLanguageResultExecution timeMemory
1189714xiaowuc1공장들 (JOI14_factories)C++17
100 / 100
2142 ms317124 KiB
#include <algorithm> #include <array> #include <bitset> #include <cassert> #include <chrono> #include <cstring> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <numeric> #include <queue> #include <random> #include <set> #include <sstream> #include <stack> #include <vector> using namespace std; // BEGIN NO SAD #define rep(i, a, b) for(int i = a; i < (b); ++i) #define trav(a, x) for(auto& a : x) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define eb emplace_back #define lb lower_bound #define ub upper_bound typedef vector<int> vi; #define f first #define s second #define derr if(1) cerr void __print(int x) {cerr << x;} void __print(long x) {cerr << x;} void __print(long long x) {cerr << x;} void __print(unsigned x) {cerr << x;} void __print(unsigned long x) {cerr << x;} void __print(unsigned long long x) {cerr << x;} void __print(float x) {cerr << x;} void __print(double x) {cerr << x;} void __print(long double x) {cerr << x;} void __print(char x) {cerr << '\'' << x << '\'';} void __print(const char *x) {cerr << '\"' << x << '\"';} void __print(const string &x) {cerr << '\"' << x << '\"';} void __print(bool x) {cerr << (x ? "true" : "false");} template<typename T, typename V> void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ", "; __print(x.second); cerr << '}';} template<typename T> void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? ", " : ""), __print(i); cerr << "}";} void _print() {cerr << "]\n";} template <typename T, typename... V> void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);} #define debug(x...) cerr << "\e[91m"<<__func__<<":"<<__LINE__<<" [" << #x << "] = ["; _print(x); cerr << "\e[39m" << flush; // END NO SAD template<class Fun> class y_combinator_result { Fun fun_; public: template<class T> explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {} template<class ...Args> decltype(auto) operator()(Args &&...args) { return fun_(std::ref(*this), std::forward<Args>(args)...); } }; template<class Fun> decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun)); } template<class T> bool updmin(T& a, T b) { if(b < a) { a = b; return true; } return false; } template<class T> bool updmax(T& a, T b) { if(b > a) { a = b; return true; } return false; } typedef int64_t ll; #ifdef fread_unlocked #define fread fread_unlocked #endif #ifdef fwrite_unlocked #define fwrite fwrite_unlocked #endif #define INPUT_SIZE 30000000 #define OUTPUT_SIZE 5000000 int _i0=0,_o0=0; char _,_n,__[22],_i[INPUT_SIZE+5],_o[OUTPUT_SIZE+5]; #define su(x) do{for(x=_i[_i0++]-48;47<(_=_i[_i0++]);x=x*10+_-48);}while(0) void pu(long long x) {_=0;do __[_++]=x%10;while(x/=10);while(_--)_o[_o0++]=__[_]+'0';} mt19937 g1(0x48); ll get_random_int(ll a, ll b) { return uniform_int_distribution<ll>(a, b)(g1); } struct koosaga { vector<vector<array<ll, 2>>> centroidtovertexdist; // <vertex> -> <centroid, dist> int n; int rootcentroid; vector<ll> lhsclosest; vector<int> lhscn; int cn; ll qry(vector<int>& lhs, vector<int>& rhs) { cn++; auto upd = [&](int idx, ll amt) -> void { if(lhscn[idx] != cn) { lhscn[idx] = cn; lhsclosest[idx] = 1e18; } updmin(lhsclosest[idx], amt); }; for(int out: lhs) { for(auto [centroid, weight]: centroidtovertexdist[out]) { upd(centroid, weight); } } ll ret = 1e18; for(int out: rhs) { for(auto [centroid, weight]: centroidtovertexdist[out]) { if(weight < ret && lhscn[centroid] == cn) updmin(ret, weight + lhsclosest[centroid]); } } return ret; } koosaga(){} koosaga(vector<array<int, 3>>& e) { n = sz(e) + 1; vector<int> nxtid(2*n-2, -1); vector<int> startid(n, -1); vector<int> to(2*n-2, -1); vector<int> weights(2*n-2); for(int i = 0; i < sz(e); i++) { auto [a, b, w] = e[i]; to[2*i] = b; weights[2*i] = w; nxtid[2*i] = startid[a]; startid[a] = 2*i; to[2*i+1] = a; weights[2*i+1] = w; nxtid[2*i+1] = startid[b]; startid[b] = 2*i+1; } centroidtovertexdist.resize(n); lhsclosest.resize(n); lhscn.resize(n); rootcentroid = -1; vector<int> seen(n); vector<int> par(n); vector<int> treesz(n); vector<bool> processed(n); int centroiditer = 0; vector<int> postorder(n); vector<array<ll, 3>> q(n); auto init = y_combinator([&](auto initself, const int srcv) -> int { assert(!processed[srcv]); auto getcentroid = [&]() -> int { seen[srcv] = ++centroiditer; int ql = 0; int qr = 0; postorder[qr++] = srcv; while(ql < qr) { int curr = postorder[ql++]; treesz[curr] = 1; for(int id = startid[curr]; id >= 0; id = nxtid[id]) { int nv = to[id]; if(!processed[nv] && seen[nv] != centroiditer) { seen[nv] = centroiditer; par[nv] = curr; postorder[qr++] = nv; } } } int totnodes = qr; for(int i = qr-1; i > 0; i--) { treesz[par[postorder[i]]] += treesz[postorder[i]]; if(2*treesz[postorder[i]] >= totnodes) return postorder[i]; } return srcv; }; int centroid = getcentroid(); { int ql = 0; int qr = 0; q[qr++] = {centroid, 0, -1}; while(ql < qr) { auto [v, w, p] = q[ql++]; centroidtovertexdist[v].pb({centroid, w}); for(int id = startid[v]; id >= 0; id = nxtid[id]) { int nv = to[id]; int nw = weights[id]; if(processed[nv] || nv == p) continue; q[qr++] = {nv, w+nw, v}; } } } sort(all(centroidtovertexdist[centroid])); processed[centroid] = true; for(int id = startid[centroid]; id >= 0; id = nxtid[id]) { int nv = to[id]; if(processed[nv]) continue; initself(nv); } return centroid; }); rootcentroid = init(get_random_int(0, n-1)); } }; koosaga koo; void Init(int N, vector<array<int, 3>>& edges){ koo = koosaga(edges); } long long Query(vector<int>& lhs, vector<int>& rhs){ return koo.qry(lhs, rhs); } void Init(int N, int A[], int B[], int D[]){ vector<array<int, 3>> edges(N-1); for(int i = 0; i < N-1; i++) edges[i] = {A[i], B[i], D[i]}; koo = koosaga(edges); } long long Query(int S, int X[], int T, int Y[]){ vector<int> lhs(S), rhs(T); for(int i = 0; i < S; i++) lhs[i] = X[i]; for(int i = 0; i < T; i++) rhs[i] = Y[i]; return koo.qry(lhs, rhs); } /* void solve() { int n, q; su(n); su(q); vector<array<int, 3>> edges(n-1); for(auto& x: edges) { su(x[0]); su(x[1]); su(x[2]); } Init(n, edges); while(q--) { int S, T; su(S); su(T); vector<int> a(S), b(T); for(auto& x: a) su(x); for(auto& x: b) su(x); pu(Query(a, b)); _o[_o0++]='\n'; } } // what would chika do // are there edge cases (N=1?) // are array sizes proper (scaled by proper constant, for example 2* for koosaga tree) // integer overflow? // DS reset properly between test cases // are you doing geometry in floating points // are you not using modint when you should int main() { fread(_i,1,INPUT_SIZE,stdin); solve(); fwrite(_o,1,_o0,stdout); //ios_base::sync_with_stdio(false); //cin.tie(NULL); //solve(); } */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...