Submission #1103059

#TimeUsernameProblemLanguageResultExecution timeMemory
1103059ASN49KHarbingers (CEOI09_harbingers)C++14
100 / 100
118 ms23844 KiB
//solution with persistent cht(without needing to be amortized complexity because of rollback) //the stratagy is that we use binary lifting(the O(n) option for better memory) //https://codeforces.com/blog/entry/51684 (the blog for persistent cht) #include <bits/stdc++.h> #define all(x) x.begin(),x.end() #define pb push_back using namespace std; using i64=long long; const int inf=1e9; const i64 INF=1e18; const int N=100'000; const int LG=16; struct line { i64 a,b; i64 calc(int x) { return x*a+b; } }; double intersect(const line& line1,const line& line2) { //if(line1.a==line2.b)return -1e18; return (double)(line2.b-line1.b)/(double)(line1.a-line2.a); } bool better(const line& line1,const line& line2,const line& line3) { return intersect(line1,line3)<=intersect(line1,line2); } struct edge { int to,cost; }; struct cht_node { line l; int next,jump,jump_cnt; }; int n; int cost_start[N],cost_km[N]; i64 dp[N],h[N]; vector<cht_node>nodes; vector<edge>adj[N]; void insert(int x,int parent) { int cnt=0; while(parent!=0 && better(nodes[nodes[parent].next].l,nodes[parent].l,nodes[x].l)) { cnt++; int jump=nodes[parent].jump; if(jump!=0 && better(nodes[nodes[jump].next].l,nodes[jump].l,nodes[x].l)) { parent=jump; } else { parent=nodes[parent].next; } } assert(cnt<=100); nodes[x].next=parent; if(parent!=0 && nodes[parent].jump!=0 && nodes[parent].jump_cnt==nodes[nodes[parent].jump].jump_cnt) { nodes[x].jump=nodes[nodes[parent].jump].jump; nodes[x].jump_cnt=2*nodes[parent].jump_cnt+1; } else { nodes[x].jump=parent; nodes[x].jump_cnt=1; } } i64 query(int x,int cost) { int cnt=0; while(x!=0 && intersect(nodes[nodes[x].next].l,nodes[x].l)>cost) { cnt++; int jump=nodes[x].jump; if(jump!=0 && intersect(nodes[nodes[jump].next].l,nodes[jump].l)>cost) { x=jump; } else { x=nodes[x].next; } } assert(cnt<=100); return nodes[x].l.calc(cost); } void dfs(int nod,int tt) { for(auto &v:adj[nod]) { if(v.to!=tt) { int c=v.to; h[c]=h[nod]+v.cost; dp[c]=h[c]*cost_km[c]+cost_start[c]-query(nod,cost_km[c]); nodes[c].l={h[c],-dp[c]}; insert(c,nod); dfs(c,nod); } } } main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin>>n; nodes.resize(n); for(int i=1;i<n;i++) { int x,y,z; cin>>x>>y>>z; x--; y--; adj[x].pb({y,z}); adj[y].pb({x,z}); } for(int i=1;i<n;i++) { cin>>cost_start[i]>>cost_km[i]; } nodes[0].l={0,0}; dfs(0,0); for(int i=1;i<n;i++)cout<<dp[i]<<' '; }

Compilation message (stderr)

harbingers.cpp:109:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  109 | main()
      | ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...