P8575 「DTOI-2」星之河 题解
P8575 「DTOI-2」星之河 题解
题目描述
题目解法
看题目就能感觉到是一道求偏序的题。所以我们先找偏序关系。
自然而然地联想到 dfs 序。
先求出每个点的 dfs 序
如果点
综上,可以得出
乍一看,好像是个四维偏序 (cdq 套 cdq)
但是由于最后一组条件比较特殊,可以化为三维偏序。
使用 cdq 分治。如果不会建议先做:【模板】三维偏序
在三维偏序模板中,用树状数组统计答案的时候统计的是
在本题中,用树状数组统计答案的时候我们统计
除此之外就是裸的 cdq 分治。
同时需要注意一下排序部分
Code
#include<bits/stdc++.h> using namespace std; #define maxn 200005 vector<int> e[maxn]; int dfn[maxn], siz[maxn]; void dfs(int u, int f) { dfn[u]=++*dfn; for(auto v:e[u]) if(v!=f) dfs(v, u), siz[u]+=siz[v]+1; } struct st { int x, y, l, r, id; st(int X, int Y, int L, int R, int I): id(I), x(X), y(Y), l(L), r(R){} }; bool cmp1(st a, st b) { if(a.x!=b.x) return a.x<b.x; if(a.y!=b.y) return a.y<b.y; return a.l>b.l; } bool cmp2(st a, st b) { if(a.y!=b.y) return a.y<b.y; if(a.l!=b.l) return a.l>b.l; return a.x<b.x; } vector<st> vc; template<typename Tp> struct BIT:vector<Tp> { void modify(size_t i, Tp v) {for(;i<this->size();i+=i&-i) (*this)[i]+=v;} Tp query(size_t i) {Tp r=0; for(;i;i-=i&-i) r+=(*this)[i]; return r;} }; BIT<int> ta; int ans[maxn]; void cdq(int l, int r) { if(l==r) return; int mid=(l+r)>>1; cdq(l, mid); cdq(mid+1, r); sort(vc.begin()+l, vc.begin()+r+1, cmp2); for(int i=l;i<=r;i++) if(vc[i].x<=mid) ta.modify(vc[i].l, 1); else ans[vc[i].id]+=ta.query(vc[i].r)-ta.query(vc[i].l-1); for(int i=l;i<=r;i++) if(vc[i].x<=mid) ta.modify(vc[i].l, -1); } signed main() { int n; cin>>n; ta.resize(n+5); for(int i=1, u, v;i<n;i++) { cin>>u>>v; e[u].emplace_back(v); e[v].emplace_back(u); } dfs(1, 0); for(int i=1, r, b;i<=n;i++) { cin>>r>>b; vc.emplace_back(r, b, dfn[i], min(dfn[i]+siz[i], n), i); } sort(vc.begin(), vc.end(), cmp1); for(int i=0;i<vc.size();i++) vc[i].x=i; cdq(0, n-1); for(int i=1;i<=n;i++) if(ans[i]) cout<<ans[i]<<'\n'; }
本文作者:Jimmy-LEEE
本文链接:https://www.cnblogs.com/redacted-area/p/18379526
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步