题目链接:DongDong数颜色
题意:给出一颗有根树树(1为根),每个节点有不同的点权,m次询问,询问以u为根节点的每个子树中不同颜色的个数。
首先预处理出dfs序,那么以u为根节点的子树可以转化为查询区间内不同数的个数。
我们可以用一个树状数组来维护每个数最后一次出现的位置。
比如查询[1,r]区间内的不同的数的个数,我们只需要设置一个变量j从1一直遍历到r,遇到某一个前面已经出现的数字就将他之前出现过的位置减1,将现在的位置处的值加1,再将这个标记更新为现在的位置:
其中w[]数组为某一位置的数是谁,pos是标记这个数最后一次是在哪出现的,初始为0,updata(int x,int val)为树状数组单点更新
int r;
for(int j=1;j<=r;++j){
if(pos[w[j]]) updata(pos[w[j]],-1);
pos[w[j]]=j;
updata(j,1);
}
有m次查询,我们可以将m次查询按照区间右端点排序,那么将变量j从1扫到n就会使得所有区间均被按顺序修改。
那么这道题就解决了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
int L[maxn],R[ma