线段树合并求查错
  • 板块学术版
  • 楼主ker_xyxyxyx_xxs
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/8/3 14:18
  • 上次更新2023/11/4 12:09:01
查看原帖
线段树合并求查错
335477
ker_xyxyxyx_xxs楼主2021/8/3 14:18

RT

P3605 [USACO17JAN]Promotion Counting P

# include <iostream>
# include <cstdio>
# include <algorithm>

using namespace std;
const int N = 1e5 + 5;
typedef struct {
	int ls , rs , Kikyo_;
}Tr;
Tr tr[N * 4];
typedef struct {
	int x , y , next;
}Edge;
Edge edge[N * 4];
int E = 0 , elast[N];
void add(int x , int y) {
	E ++;
	edge[E].x = x;
	edge[E].y = y;
	edge[E].next = elast[x];
	elast[x] = E;
}
int n;
int a[N] , val[N];
int root[N];
int tot = 0;
void build(int &Root , int l , int r , int val) {
	Root = ++ tot;
	tr[Root].Kikyo_ = 1;
	if (l == r) return ;
	int mid = (l + r) >> 1;
	if (val <= mid) build(tr[Root].ls , l , mid , val);
	else build(tr[Root].rs , mid + 1 , r , val);
	
}
void merge(int &x , int y) {
	if (!x || !y) {
		x += y;
		return ;
	}
	tr[x].Kikyo_ += tr[y].Kikyo_;
	merge(tr[x].ls , tr[y].ls);
	merge(tr[x].rs , tr[y].rs);

}
int ans[N];

int query(int Root , int l , int r , int x , int y) {
	if (x <= l && r <= y) return tr[Root].Kikyo_;
	int ans = 0 , mid = (l + r) >> 1;
	if (x <= mid) ans += query(tr[Root].ls , l , mid , x , y);
	if (y > mid) ans += query(tr[Root].rs , mid + 1 , r , x , y);
	return ans;
}
int m;
void dfs(int x) {
	for (int i = elast[x] ; i ; i = edge[i].next) {
		int y = edge[i].y;
		dfs(y);
		merge(root[x] , root[y]);
	}
	ans[x] = query(root[x] , 1 , n , val[x] + 1 , n);
}


int x;
int main() {
	cin >> n;
	for (int i = 1 ; i <= n ; i ++) {
		scanf("%d" , &a[i]);
		val[i] = a[i];
	}
	for (int i = 2 ; i <= n ; i ++) {
		scanf("%d" , &x);
		add(x , i);
	}
	sort(a + 1 , a + 1 + n);
	for (int i = 1 ; i <= n ; i ++) {
		val[i] = lower_bound(a + 1 , a + 1 + n, val[i]) - a;
		build(root[i] , 1 , n , val[i]);
	}
	dfs(1);
	for (int i = 1 ; i<= n ; i ++) {
		printf("%d\n" , &ans[i]);
	}
	return 0;
} 
 
2021/8/3 14:18
加载中...