Codeforces - 375D ( dfs序 + 莫队 )

Codeforces - 375D ( 莫队 )

题目链接:https://codeforces.com/contest/375/problem/D

题意:给出一棵 n 个结点的树,每个结点有一个颜色 c i 。 询问 q 次,每次询问以 v 结点为根的子树中,出现次数 ≥k 的颜色有多少种。树的根节点是1。

思路:dfs序上暴力莫队。注意dfs序和原节点编号的转换,用dfn和rev来保存。

具体实现的时候可以直接用 via[i] 表示第 i 个颜色的出现次数,ci [ i ] 表示出现次数多于 i 的颜色的种类

由于左右端点移动的时候只会对一个ci [ i ] 产生影响,所以修改是O(1)的

input

8 5
1 2 2 3 3 2 3 3
1 2
1 5
2 3
2 4
5 6
5 7
5 8
1 2
1 3
1 4
2 3
5 3

output

2
2
1
0
1

代码:

#include 

using namespace std;

const int maxn = 2e5+10;
int dfn[maxn],col[maxn],via[maxn],sz[maxn];
int ans[maxn],ci[maxn],rev[maxn];
vector G[maxn];
int n,m,tim,block;
struct node {
    int l,r,k,id;
}q[maxn];

int rule( node a, node b )
{
    if ( a.l/block==b.l/block ) return a.r> n >> m;
    for ( int i=1; i<=n; i++ ) scanf("%d",&col[i]);
    for ( int i=1; il ) {
            del(l++);
        }
        while ( q[i].lr ) {
            add(++r);
        }
        while ( q[i].r

 

你可能感兴趣的:(其他补题)