Submission #865257

#TimeUsernameProblemLanguageResultExecution timeMemory
865257LittleOrangeDesignated Cities (JOI19_designated_cities)C++17
100 / 100
551 ms109732 KiB
#include<bits/stdc++.h> using namespace std; using ll = long long; struct obj{ ll to,c0,c1;// to, back }; struct segtree{ ll n; vector<pair<ll,ll>> dat; vector<ll> tag; segtree(ll n):n(n),dat(n<<2),tag(n<<2,0){} void set(ll i, ll l, ll r, ll x, pair<ll,ll> v){ if (l == r) dat[i] = v; else{ ll m = l+r>>1; if (x<=m) set(i<<1,l,m,x,v); else set(i<<1|1,m+1,r,x,v); dat[i] = max(dat[i<<1],dat[i<<1|1]); } } void set(ll x, pair<ll,ll> v){ set(1,0,n-1,x,v); } void add(ll i, ll v){ dat[i].first += v; tag[i] += v; } void push(ll i){ add(i<<1,tag[i]); add(i<<1|1,tag[i]); tag[i] = 0; } void add(ll i, ll l, ll r, ll ql, ll qr, ll v){ if (ql<=l&&r<=qr) add(i,v); else{ push(i); ll m = l+r>>1; if (ql<=m) add(i<<1,l,m,ql,qr,v); if (qr>m) add(i<<1|1,m+1,r,ql,qr,v); dat[i] = max(dat[i<<1],dat[i<<1|1]); } } void add(ll ql, ll qr, ll v){ add(1,0,n-1,ql,qr,v); } ll get(){ return dat[1].second; } }; int main(){ ios::sync_with_stdio(0);cin.tie(0); ll n,q; cin >> n; vector<vector<obj>> con(n); ll tot = 0; for(ll i = 1;i<n;i++){ ll a,b,c,d; cin >> a >> b >> c >> d;a--;b--; con[a].push_back({b,c,d}); con[b].push_back({a,d,c}); tot += c+d; } ll leaf_cnt = 0; for(auto &o : con) if (o.size()==1) leaf_cnt++; cin >> q; bool use16 = false; if (n<=16&&use16){ vector<ll> ans(n+1,tot); //vector<ll> ch(n+1,0); ll cur = tot; vector<vector<ll>> used(n,vector<ll>(n,0)); function<void(ll,ll)> dfs; dfs = [&](ll i, ll p){ for(obj l : con[i]){ if (l.to!=p){ if (!used[i][l.to]){ used[i][l.to] = 1; cur -= l.c1; } dfs(l.to,i); } } }; for(ll x = 1;x<(1<<n);x++){ cur = tot; for(ll i = 0;i<n;i++) for(ll j = 0;j<n;j++) used[i][j] = 0; ll lvl = __builtin_popcountll(x); for(ll i = 0;i<n;i++) if(x>>i&1) dfs(i,-1); //if (cur<ans[lvl]) ch[lvl] = x; ans[lvl] = min(ans[lvl],cur); } while(q--){ ll e; cin >> e; cout << ans[e] << "\n"; //for(ll i = 0;i<n;i++) cout << (ch[e]>>i&1); //cout << "\n"; } return 0; } vector<ll> dp(n,0); { function<ll(ll,ll)> dfs; dfs = [&](ll i, ll p){ ll cur = 0; for(obj l : con[i]){ if (l.to!=p){ cur += l.c1 + dfs(l.to,i); } } return cur; }; dp[0] = dfs(0,-1); } { function<void(ll,ll,ll)> dfs; dfs = [&](ll i, ll p, ll v){ dp[i] = v; for(obj l : con[i]){ if (l.to!=p){ dfs(l.to,i,v+l.c0-l.c1); } } }; dfs(0,-1,dp[0]); } ll ans_1 = tot; for(ll i : dp) ans_1 = min(tot-i,ans_1); ll ans_2 = tot, tg0=-1,tg1=-1; vector<ll> go(n,0),ch(n,0),tg(n,0); { function<void(ll,ll)> dfs; dfs = [&](ll i, ll p){ tg[i] = i; ll de = 0; for(obj l : con[i]){ if (l.to!=p){ dfs(l.to,i); go[i] += go[l.to]+l.c0; if (go[l.to]+l.c0 - ch[l.to]>de) tg[i] = tg[l.to]; de = max(de,go[l.to]+l.c0 - ch[l.to]); } } ch[i] = go[i] - de; }; dfs(0,-1); } { function<void(ll,ll,ll)> dfs; dfs = [&](ll i, ll p, ll v){ ll w = v; for(obj l : con[i]){ if (l.to!=p){ w += go[l.to]+l.c0; } } ll a = 0,b = 0,t0=-1,t1=-1; for(obj l : con[i]){ if (l.to!=p){ dfs(l.to,i,w-(go[l.to]+l.c0)+l.c1); ll cur = go[l.to]+l.c0 - ch[l.to]; if (cur>=a){ t1 = t0; t0 = tg[l.to]; b = a; a = cur; }else if(cur>=b){ t1 = tg[l.to]; b = cur; } } } if (t1!=-1){ if (w-a-b<ans_2){ tg0 = t0; tg1 = t1; } ans_2 = min(ans_2, w-a-b); }else if (p==-1){ if (w-a<ans_2){ tg0 = t0; tg1 = i; } ans_2 = min(ans_2, w-a); } }; dfs(0,-1, 0); } //cout << "tgs: " << tg0+1 << " " << tg1+1 << "\n"; vector<ll> ans(n+1,-1); ans[1] = ans_1; ans[2] = ans_2; for(ll i = leaf_cnt;i<=n;i++) ans[i] = 0; bool use2000 = false; if (n<=2000&&use2000){ vector<ll> pre(n,-1), tag(n,0); { function<void(ll,ll)> dfs; dfs = [&](ll i, ll p){ pre[i] = p; for(obj l : con[i]){ if (l.to!=p){ dfs(l.to,i); } } }; dfs(tg0,-1); } { ll cur = tg1; tag[cur] = 1; while(cur != tg0){ cur = pre[cur]; tag[cur] = 1; } } ll it = 3; while(it<=leaf_cnt){ vector<ll> h(n,0); ll cur = 0, value = 0, cur_ans = 0; function<void(ll,ll)> dfs; dfs = [&](ll i, ll v){ h[i] = tag[i]?0:v; for(obj l : con[i]){ if (l.to!=pre[i]){ dfs(l.to,l.c0+h[i]); if (!tag[l.to]) cur_ans += l.c0; } } if (h[i]>value){ value = h[i]; cur = i; } }; dfs(tg0,0); ans[it-1] = cur_ans; tag[cur] = 1; while(cur != tg0){ cur = pre[cur]; tag[cur] = 1; } it++; } } { vector<ll> h(n,0),lvl(n,0),L(n),R(n); ll cur_ans = 0; vector<ll> pre(n,-1), price(n,0); { function<void(ll,ll)> dfs; dfs = [&](ll i, ll p){ pre[i] = p; for(obj l : con[i]){ if (l.to!=p){ dfs(l.to,i); price[l.to] = l.c0; cur_ans += l.c0; } } }; dfs(tg0,-1); } { ll it = 0; function<void(ll,ll,ll)> dfs; dfs = [&](ll i, ll v,ll lv){ L[i] = it++; h[i] = v; lvl[i] = lv; for(obj l : con[i]){ if (l.to!=pre[i]){ dfs(l.to,l.c0+v,lv+1); } } R[i] = it++; }; dfs(tg0,0,0); } segtree t(n*2); for(ll i = 0;i<n;i++){ t.set(L[i],make_pair(h[i],i)); t.set(R[i],make_pair(h[i],i)); } { ll cur = tg1; while(price[cur]>0){ t.add(L[cur],R[cur],-price[cur]); cur_ans -= price[cur]; price[cur] = 0; cur = pre[cur]; } } for(ll e = 3;e<leaf_cnt;e++){ ll cur = t.get(); while(price[cur]>0){ t.add(L[cur],R[cur],-price[cur]); cur_ans -= price[cur]; price[cur] = 0; cur = pre[cur]; } ans[e] = cur_ans; } } while(q--){ ll e; cin >> e; cout << ans[e] << "\n"; } }

Compilation message (stderr)

designated_cities.cpp: In member function 'void segtree::set(ll, ll, ll, ll, std::pair<long long int, long long int>)':
designated_cities.cpp:15:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   15 |             ll m = l+r>>1;
      |                    ~^~
designated_cities.cpp: In member function 'void segtree::add(ll, ll, ll, ll, ll, ll)':
designated_cities.cpp:37:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   37 |             ll m = l+r>>1;
      |                    ~^~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...