大小接近的点对 树状数组 + dp

大小接近的点对

树状数组

1,不需要什么树上莫队算法,主要我也不会,根本没见过这个算法,太菜了。 口胡一下莫队吧,应该可以跑一个dfs序,然后只需要求dfs序中 [l, r]之间满足大小接近的点对数量就行了,但是莫队我不太熟悉,留坑🕳
2,dp的思想,f[root] = sum(f[son]) + (root 和 子树中的距离小于等于k的点的数量即可)
3,暴力肯定O(n^2)的,考虑树状数组,当然为每个点开一个树状数组空间不够,合并两个子树的树状数组也不行,故采取维护一个树状数组的方法
4,考虑dfs,dfs肯定是从父节点进入的根节点的,故第一次访问到r节点时,求其树状数组中大小接近的点对数量 就是该子树外面的部分点和r节点的满足的数量。 等回溯到r节点时,以r为根的子树全部遍历完了,再次求 树状数组中大小接近的点对数量 ,此时的值减去 第一次遍历的值即 子树 与 r节点的贡献。
5,注意离散化时可以顺便吧 a[i] - k, a[i] + k 也加入 进行离散化,这样可以减少编码复杂度

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define fi first
#define se second
#define pb push_back

#define foa(x, y, z) for(int x = (y), ooo = (z); x <= z; ++x)
#define fos(x, y, z) for(int x = (y), ooo = (z); x >= z; --x)
#define ckmax(x, y) ((x) < (y) ? (x) = (y), 1 : 0)
#define ckmin(x, y) ((x) > (y) ? (x) = (y), 1 : 0)
#define lbt(x) ((x) & (-x))
#define all(x) x.begin(), x.end()

typedef pair<int, int> pii;
typedef long long ll;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 10;
int n, m;
int c[N];
void add(int x, int v)
{
	for(; x < N; x += lbt(x)) c[x] += v;
}
int ask(int x)
{
	x = min(x, N - 1);
	x = max(x, 0ll);
	int res = 0;
	for(; x; x -= lbt(x)) res += c[x];
	return res;
}
int k, a[N], f[N];
vector<int> gr[N];
vector<int> v;
int id(int x)
{
	return lower_bound(all(v), x) - v.begin() + 1;
}
void dfs(int r, int fa)
{
	f[r] = 1;
	int t = ask(id(a[r] + k)) - ask(id(a[r] - k));
	for(auto &x : gr[r]) {
		if(x == fa) continue;
		dfs(x, r);
		f[r] += f[x];
	}
	f[r] += ask(id(a[r] + k)) - ask(id(a[r] - k)) - t;
	add(id(a[r]), 1);
}
void solve() {
	cin >> n >> k;
	foa(i, 1, n) {
		cin >> a[i];
		v.pb(a[i]);
		v.pb(a[i] - k);
		v.pb(a[i] + k);
	}
	foa(i, 2, n){
		int fa;
		cin >> fa;
		gr[fa].pb(i);
	}
	sort(all(v));
	v.erase(unique(all(v)), v.end());
	
	dfs(1, 0);
	foa(i, 1, n) cout << f[i] << endl;
}
signed main() {
	// ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	solve();
	return 0;
}
posted @   1564269628  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示