http://codeforces.com/problemset/problem/375/D

树莫队就是把树用dfs序变成线性的数组。 (原数组要根据dfs的顺序来变化)

然后和莫队一样的区间询问。

这题和普通莫队有点区别,他需要的不单单是统计区间元素种类个数,是区间元素种类个数 >= k[i]的个数。

考虑最简单的用bit维护,复杂度多了个log

观察到每次只需要 + 1  或者 -1

用一个数组sum[k]表示种类数大于等于k的ans

在numc[val]++之后,sum[numc[val]]++,表明这个种类出现次数是numc[val]次的贡献递增1

在num[val]--之前,就需要把sum[numc[val]]--,表明贡献减1了

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 1e5 + ;
struct Edge {
int u, v, tonext;
}e[maxn * ];
int first[maxn], num;
int c[maxn];
void addEdge(int u, int v) {
++num;
e[num].u = u, e[num].v = v, e[num].tonext = first[u];
first[u] = num;
}
int L[maxn], R[maxn], dfs_clock;
int color[maxn];
void dfs(int cur, int fa) {
L[cur] = ++dfs_clock;
color[dfs_clock] = c[cur];
for (int i = first[cur]; i; i = e[i].tonext) {
int v = e[i].v;
if (fa == v) continue;
dfs(v, cur);
}
R[cur] = dfs_clock;
}
int magic;
struct Node {
int L, R, k, id;
bool operator < (const struct Node & rhs) const {
if (L / magic != rhs.L / magic) return L / magic < rhs.L / magic;
else return R < rhs.R;
}
}query[maxn];
int ans[maxn], numc[maxn];
int bit[maxn];
int lowbit(int x) {
return x & (-x);
}
void add(int pos, int val) {
while (pos) {
bit[pos] += val;
pos -= lowbit(pos);
}
}
int ask(int pos) {
int ans = ;
while (pos <= maxn - ) {
ans += bit[pos];
pos += lowbit(pos);
}
return ans;
}
int suffix[maxn];
void work() {
int n, m;
cin >> n >> m;
for (int i = ; i <= n; ++i) cin >> c[i];
for (int i = ; i <= n - ; ++i) {
int u, v;
scanf("%d%d", &u, &v);
addEdge(u, v);
addEdge(v, u);
}
dfs(, );
magic = (int)sqrt(n + 0.5);
for (int i = ; i <= m; ++i) {
int which, k;
scanf("%d%d", &which, &k);
query[i].L = L[which], query[i].R = R[which], query[i].k = k;
query[i].id = i;
}
sort(query + , query + + m);
int L = , R = ;
int temp = ;
for (int i = ; i <= m; ++i) {
while (R < query[i].R) {
++R;
suffix[++numc[color[R]]]++;
}
while (R > query[i].R) {
suffix[numc[color[R]]--]--;
--R;
}
while (L < query[i].L) {
suffix[numc[color[L]]--]--;
L++;
}
while (L > query[i].L) {
L--;
suffix[++numc[color[L]]]++;
}
ans[query[i].id] = suffix[query[i].k];
}
for (int i = ; i <= m; ++i) {
printf("%d\n", ans[i]);
}
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

Tree and Queries CodeForces - 375D 树上莫队的更多相关文章

  1. SPOJ COT2 - Count on a tree II(LCA+离散化+树上莫队)

    COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from  ...

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

    题目链接  Tree and Queries 题目大意  给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...

  3. spoj COT2 - Count on a tree II 树上莫队

    题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的,  受益匪浅.. #include <iostream> #include < ...

  4. 【SPOJ】Count On A Tree II(树上莫队)

    [SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...

  5. 「日常训练&知识学习」莫队算法(二):树上莫队(Count on a tree II,SPOJ COT2)

    题意与分析 题意是这样的,给定一颗节点有权值的树,然后给若干个询问,每次询问让你找出一条链上有多少个不同权值. 写这题之前要参看我的三个blog:Codeforces Round #326 Div. ...

  6. COT2 - Count on a tree II(树上莫队)

    COT2 - Count on a tree II You are given a tree with N nodes. The tree nodes are numbered from 1 to N ...

  7. Codeforces 852I Dating 树上莫队

    Dating 随便树上莫队搞一搞就好啦. #include<bits/stdc++.h> #define LL long long #define LD long double #defi ...

  8. SP10707 COT2 - Count on a tree II (树上莫队)

    大概学了下树上莫队, 其实就是在欧拉序上跑莫队, 特判lca即可. #include <iostream> #include <algorithm> #include < ...

  9. SPOJ COT2 Count on a tree II (树上莫队,倍增算法求LCA)

    题意:给一个树图,每个点的点权(比如颜色编号),m个询问,每个询问是一个区间[a,b],图中两点之间唯一路径上有多少个不同点权(即多少种颜色).n<40000,m<100000. 思路:无 ...

随机推荐

  1. git rebase小计(转)

    git rebase,顾名思义,就是重新定义(re)起点(base)的作用,即重新定义分支的版本库状态.要搞清楚这个东西,要先看看版本库状态切换的两种情况: 我们知道,在某个分支上,我们可以通过git ...

  2. python mysql 查询返回字典结构

    cur = self.conn.cursor(MySQLdb.cursors.DictCursor)加上MySQLdb.cursors.DictCursor可以返回字典结构 {列名:值} class ...

  3. js遍历for,forEach, for in,for of

    ECMAScript5(es5)有三种for循环 简单for for in forEach ECMAScript6(es6)新增 for of 简单for for是循环的基础语法,也是最常用的循环结构 ...

  4. 使用雅虎YUI Compressor压缩JS过程心得记录

    对待发布的项目进行测试时,发现js下载量比较大,从jquery的min版想到了压缩项目中的js文件.很简单的google之(在此,强调一下google的重要性),搜到一个叫做YUI Compresso ...

  5. C# 播放音乐

    用 .NET 自带的类库 System.Media 下面的 SoundPlayer 来播放音乐的方式,此种方式使用托管代码,应该是更为可取的方式吧 使用起来非常简单,下面稍作说明: . 支持同步.异步 ...

  6. Spring Boot 专栏

    http://blog.csdn.net/column/details/spring-boot.html?&page=2

  7. [nowCoder] 两个长度相同有序数组的中位数

    给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数.例如:arr1 = {1,2,3,4};arr2 = {3,4,5,6};一共8个数则上中位数是第4个数,所以返回 ...

  8. .clearfix:after

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. fdisk查看硬盘分区表

    fdisk [选项] <磁盘>    更改分区表 fdisk [选项] -l <磁盘> 列出分区表 fdisk -s <分区>        给出分区大小(块数) ...

  10. Some of your uncommitted changes would be overwritten by syncing.Please commit your changes then try

    解决方法有三种,在GitHub shel中输入以下命令,任选一种方法就能解决问题 git reset --hard HEAD -- Destructive. When you do this you' ...