Submission #1240386

#TimeUsernameProblemLanguageResultExecution timeMemory
1240386hengliaoTree (IOI24_tree)C++20
100 / 100
196 ms89032 KiB
#include "tree.h" #include<bits/stdc++.h> using namespace std; #define F first #define S second #define pll pair<ll, ll> #define vll vector<ll> #define pb push_back typedef long long ll; namespace{ const ll mxN=2e5+5; const ll inf=1e18; const ll mxM=1e6+5; struct segtreeadd{ vll tree; ll siz; void init(ll sz){ siz=sz+1; tree=vll(siz, 0); } void update(ll idx, ll val){ idx++; for(;idx<siz;idx+=(idx&(-idx))){ tree[idx]+=val; } } ll getpre(ll idx){ idx++; ll re=0; for(;idx>0;idx-=(idx&(-idx))){ re+=tree[idx]; } return re; } ll getsum(ll qlow, ll qhigh){ return getpre(qhigh)-getpre(qlow-1); } }; struct segtreemin{ vector<pll> tree; ll treelen; void init(ll sz){ treelen=sz+1; while(__builtin_popcount(treelen)!=1) treelen++; tree=vector<pll>(2*treelen, {inf, inf}); } void update(ll idx, pll val){ ll tar=idx+treelen; tree[tar]=val; tar/=2; while(tar>0){ tree[tar]=min(tree[2*tar], tree[2*tar+1]); tar/=2; } } pll getmin1(ll idx, ll low, ll high, ll qlow, ll qhigh){ if(low>=qlow && high<=qhigh){ return tree[idx]; } if(low>qhigh || high<qlow){ return {inf, inf}; } ll mid=(low+high)/2; return min(getmin1(2*idx, low, mid, qlow, qhigh), getmin1(2*idx+1, mid+1, high, qlow, qhigh)); } pll getmin(ll qlow, ll qhigh){ return getmin1(1, 0, treelen-1, qlow, qhigh); } }; segtreeadd seg1; segtreemin seg2; ll n, l, r; ll p[mxN]; ll w[mxN]; vll adj[mxN]; ll in[mxN], out[mxN]; ll timer; ll ans; vector<array<ll, 5>> eq; ll leafsum; ll prel[mxM], prer[mxM]; void dfs(ll cur){ in[cur]=timer; out[cur]=timer; timer++; for(auto &chd:adj[cur]){ dfs(chd); out[cur]=out[chd]; } } void chainupd(ll t, ll b, ll val){ seg1.update(in[b], val); if(p[t]!=-1){ seg1.update(in[p[t]], -val); } } void f(ll cur){ pll tep=seg2.getmin(in[cur], out[cur]); if(tep.F==inf) return; ll tar=tep.S; // cout<<seg1.getsum(in[cur], out[cur])<<'\n'; ll total=seg1.getsum(in[cur], out[cur]); // ll mx=seg1.getsum(in[cur], out[cur])*l-r; // ll lef=0; // ll org=seg1.getsum(in[tar], out[tar])*l; ll th=seg1.getsum(in[tar], out[tar]); eq.pb({total-th+1, 0, -w[tar], 0, tar}); eq.pb({total, total-th+1, (total-th)*w[tar], -w[tar], tar}); // ll mntar=max(org-mx, l); for(auto &chd:adj[tar]){ ll k=seg1.getsum(in[chd], out[chd]); // ll val=min(seg1.getsum(in[chd], out[chd])*l, r); // lef+=val; eq.pb({total, k, k*w[tar], 0, tar}); eq.pb({k, 0, 0, w[tar], tar}); } // ll minu=lef-mntar; // if(mx>0) ans+=w[tar]*minu; // cout<<"node: "<<tar<<' '<<lef<<' '<<mx<<'\n'; chainupd(cur, tar, -(th-1)); // cout<<"updating "<<cur<<' '<<tar<<' '<<-lef<<'\n'; seg2.update(in[tar], {inf, inf}); for(auto &chd:adj[tar]){ f(chd); } f(cur); } } void init(vector<int> P, vector<int> W) { n=P.size(); for(ll i=0;i<n;i++){ p[i]=P[i]; w[i]=W[i]; if(i>0){ adj[p[i]].pb(i); } } timer=0; dfs(0); leafsum=0; seg1.init(n); seg2.init(n); for(ll i=0;i<n;i++){ if(in[i]==out[i]){ seg1.update(in[i], 1); seg2.update(in[i], {inf, inf}); leafsum+=w[i]; } else{ seg2.update(in[i], {w[i], i}); } } f(0); for(auto &it:eq){ prel[it[1]]+=it[2]; prel[it[0]]-=it[2]; prer[it[1]]+=it[3]; prer[it[0]]-=it[3]; } for(ll i=1;i<mxM;i++){ prel[i]+=prel[i-1]; prer[i]+=prer[i-1]; } } long long query(int L, int R) { ans=0; l=L; r=R; ans+=leafsum*l; ll divi=r/l; ans+=prel[divi]*l+prer[divi]*r; return ans; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...