Submission #1161224

#TimeUsernameProblemLanguageResultExecution timeMemory
1161224brintonTwo Currencies (JOI23_currencies)C++20
100 / 100
765 ms77060 KiB
#include <bits/stdc++.h> using namespace std; #define int long long struct dataS{ // now is bit private: vector<int> tree; int N; int query(int idx){ int ans = 0; for(int i = idx;i >= 1;i -= i&-i){ ans += tree[i]; } return ans; } public: dataS(int iN){ N = iN; tree.resize(N+1); } void modify(int idx,int dv){ for(int i = idx;i <= N;i += i&-i){ tree[i] += dv; } } int query(int u,int v){ if(u > v)swap(u,v); return query(v)-query(u); } }; // ===== hld ==== vector<vector<int>> edges; vector<int> sz,par,dep,hson,rdn,top; int dfs1(int cur,int p,int cdep){ par[cur] = p; dep[cur] = cdep; int csz = 1; int maxSz = 0; int maxIdx = -1; for(auto nxt:edges[cur]){ if(nxt == p)continue; int nsz = dfs1(nxt,cur,cdep+1); if(nsz > maxSz){ maxSz = nsz; maxIdx = nxt; } csz += nsz; } hson[cur] = maxIdx; return csz; } int gt = 1; void dfs2(int cur,int p){ // dfs child first rdn[cur] = gt; gt++; if(hson[cur] != -1){ top[hson[cur]] = top[cur]; dfs2(hson[cur],cur); } for(auto nxt:edges[cur]){ if(nxt == p)continue; if(nxt == hson[cur])continue; top[nxt] = nxt; dfs2(nxt,cur); } } int hld_q(int u,int v,dataS& bit){ int ans = 0; while(top[u] != top[v]){ // cout << u << " " << v << endl; if(dep[top[u]] > dep[top[v]]){ // lift up u ans += bit.query(rdn[top[u]]-1,rdn[u]);// -1 because top[u]'s parent consider u = par[top[u]]; }else{ ans += bit.query(rdn[top[v]]-1,rdn[v]);// -1 because top[u]'s parent consider v = par[top[v]]; } } ans += bit.query(rdn[u],rdn[v]); return ans; } void hld_m(int u,int v,int dv,dataS& bit){// modify in child if(par[u] == v){ // modify u // cout << "modify" << rdn[u] << endl; bit.modify(rdn[u],dv); }else{ // modify v // cout << "modify" << rdn[v] << endl; bit.modify(rdn[v],dv); } } signed main(){ cin.tie(0); ios_base::sync_with_stdio(0); //start here int N,C,Q; cin >> N >> C >> Q; // ==== input tree === edges.resize(N+1); vector<array<int,2>> edgeUV; for(int i = 0;i < N-1;i++){ int a,b; cin >> a >> b; edges[a].push_back(b); edges[b].push_back(a); edgeUV.push_back({a,b}); } sz = par = dep = hson = rdn = top = vector<int>(N+1,0); dfs1(1,-1,0); top[1] = 1; dfs2(1,-1); // for(int i = 1;i <= N;i++)cout << rdn[i] << " ";cout << endl; // for(int i = 1;i <= N;i++)cout << top[i] << " ";cout << endl; // ==== input checkPoint ==== vector<array<int,3>> checkP;// cost,u,v for(int i = 0;i < C;i++){ int loc,cost; cin >> loc >> cost; loc--; checkP.push_back({cost,edgeUV[loc][0],edgeUV[loc][1]}); } // ===== query input offline ==== vector<array<int,5>> qry; for(int i = 0;i < Q;i++){ int u,v,g,s; cin >> u >> v >> g >> s; qry.push_back({u,v,g,s,i}); } // ==== sort CheckPoint ==== sort(checkP.begin(),checkP.end()); vector<int> ans(Q); dataS silver(N+1); dataS gold(N+1); dataS change(N+1); for(auto [cost,a,b]:checkP){ // gold.modify(a,b,1); hld_m(a,b,1,gold); } // for(int u = 1;u <= N;u++){ // for(int v = u;v <= N;v++){ // cout << u << " " << v << ":" << hld_q(u,v,gold) << endl; // } // } // cout << hld_q(1,3,gold) << endl; // return 0; auto whole = [&](int l,int r,vector<array<int,5>> cq,auto whole){ if(l > r){ // answer queries; for(auto [u,v,g,s,idx]:cq){ // cout << idx << ":" << gold.query(u,v) << " " << change.query(u,v) << endl; // cout << idx << ":" << hld_q(u,v,gold) << " " << hld_q(u,v,change) << endl; // ans[idx] = max(-1LL,g-(gold.query(u,v)-change.query(u,v))); ans[idx] = max(-1LL,g-(hld_q(u,v,gold)-hld_q(u,v,change))); } return; } // put half queries in int m = (l+r)/2; for(int i = l;i <= m;i++){ // ! full point change to hld // change.modify(checkP[i][1],checkP[i][2],1); // silver.modify(checkP[i][1],checkP[i][2],checkP[i][0]); hld_m(checkP[i][1],checkP[i][2],1,change); hld_m(checkP[i][1],checkP[i][2],checkP[i][0],silver); } vector<array<int,5>> ql,qr; for(auto [u,v,g,s,idx]:cq){ // bool ok = silver.query(u,v) <= s; bool ok = hld_q(u,v,silver) <= s; if(ok){ qr.push_back({u,v,g,s,idx}); }else{ ql.push_back({u,v,g,s,idx}); } } whole(m+1,r,qr,whole); // remove; for(int i = l;i <= m;i++){ // ! full point change to hld // change.modify(checkP[i][1],checkP[i][2],-1); // silver.modify(checkP[i][1],checkP[i][2],-checkP[i][0]); hld_m(checkP[i][1],checkP[i][2],-1,change); hld_m(checkP[i][1],checkP[i][2],-checkP[i][0],silver); } whole(l,m-1,ql,whole); }; whole(0,C-1,qry,whole); for(auto i:ans)cout << i << "\n"; } // 整體2分
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...