码迷,mamicode.com
首页 > 编程语言 > 详细

Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)

时间:2017-09-30 21:56:27      阅读:311      评论:0      收藏:0      [点我收藏+]

标签:div   val   print   树状数组   date   get   .com   names   int   

题目链接  Tree and Queries

题目大意  给出一棵树和每个节点的颜色。每次询问vj, kj

你需要回答在以vj为根的子树中满足条件的的颜色数目,

条件:具有该颜色的节点数量至少为kj。

 

(莫队居然可以过)

首先转DFS序,这样就变成了区间查询。

然后直接套用莫队,求出每次询问状态下的t[],t[k]表示当前区间内拥有k个节点的颜色数量。

然后统计t[k] + t[k + 1], ..., t[MAX]即可,这个过程用树状数组维护。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

const int N = 1e5 + 10;
const int d = N + 10;

int b[N], c[N * 3], f[N];
int in[N], out[N];
int a[N], belong[N];
int n, m, ti = 0, bs = 0;
int l, r;
int ans[N];
vector <int> v[N];

struct node{
	int v, k, id;
	int l, r;
	friend bool operator < (const node &a, const node &b){
		return belong[a.l] == belong[b.l] ? a.r < b.r : belong[a.l] < belong[b.l];
	}
} q[N];

inline void update(int x, int val){
	for (; x <= (N * 3 - 10); x += x & -x) c[x] += val;

}

inline int query(int x){
	if (x == 0) return c[x];
	int ret = 0;
	for (; x; x -= x & -x) ret += c[x];
	return ret;
}

void dfs(int x, int fa){
	in[x] = ++ti;
	for (auto u : v[x]){
		if (u == fa) continue;
		dfs(u, x);
	}
	out[x] = ti;
}


int main(){

	scanf("%d%d", &n, &m);
	rep(i, 1, n) scanf("%d", a + i);
	rep(i, 2, n){
		int x, y;
		scanf("%d%d", &x, &y);
		v[x].push_back(y);
		v[y].push_back(x);
	}
	
	dfs(1, 0);

	rep(i, 1, n) b[in[i]] = i;

	rep(i, 1, m){
		scanf("%d%d", &q[i].v, &q[i].k);
		q[i].id = i;
		q[i].l = in[q[i].v];
		q[i].r = out[q[i].v];
	}

	bs = sqrt(n);
	rep(i, 1, n) belong[i] = (i - 1) / bs + 1;
	sort(q + 1, q + m + 1);



	update(d, n);

	l = 1, r = 0;

	rep(i, 1, m){
		while (l > q[i].l){
			--l;
			update(f[a[b[l]]] + d, -1);
			++f[a[b[l]]];
			update(f[a[b[l]]] + d,  1);	
		}

		while (l < q[i].l){
			update(f[a[b[l]]] + d, -1);
			--f[a[b[l]]];
			update(f[a[b[l]]] + d, 1);
			++l;
		}

		while (r < q[i].r){
			++r;
			update(f[a[b[r]]] + d, -1);
			++f[a[b[r]]];
			update(f[a[b[r]]] + d, 1);
		}

		while (r > q[i].r){
			update(f[a[b[r]]] + d, -1);
			--f[a[b[r]]];
			update(f[a[b[r]]] + d, 1);
			--r;
		}
		ans[q[i].id] = max(0, query(N * 3 - 10) - query(q[i].k - 1 + d));
	}

	rep(i, 1, m) printf("%d\n", ans[i]);	
	return 0;
}

 

Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)

标签:div   val   print   树状数组   date   get   .com   names   int   

原文地址:http://www.cnblogs.com/cxhscst2/p/7616157.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!