P8575 「DTOI-2」星之河 题解
P8575 「DTOI-2」星之河 题解
题目描述
题目解法
看题目就能感觉到是一道求偏序的题。所以我们先找偏序关系。
\(Red_i\) 和 \(Blue_i\) 的关系题面已经给出,现在考虑子树关系。
自然而然地联想到 dfs 序。
先求出每个点的 dfs 序 \(dfn_i\),以及其子树的大小 \(size_i\)。
如果点 \(j\) 在点 \(i\) 的子树中,那么就有 \(dfn_i<dfn_j<dfn_i+size_i\)。
综上,可以得出 \(j\) 对 \(i\) 有贡献的条件:
\[Red_j\leq Red_i\wedge Blue_j\leq Blue_i \wedge dfn_i<dfn_j<dfn_i+size_i
\]
乍一看,好像是个四维偏序 (cdq 套 cdq)
但是由于最后一组条件比较特殊,可以化为三维偏序。
使用 cdq 分治。如果不会建议先做:【模板】三维偏序
在三维偏序模板中,用树状数组统计答案的时候统计的是 \([1,x_i)\) 该区间。
在本题中,用树状数组统计答案的时候我们统计 \((dfn_i,dfn_i+size_i)\) 区间。
除此之外就是裸的 cdq 分治。
同时需要注意一下排序部分 \(Blue_i,Red_i\) 升序,而 \(dfn_i\) 降序。
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';
}

浙公网安备 33010602011771号