牛客练习赛47 DongDong数颜色 (莫队算法)
链接:https://ac.nowcoder.com/acm/contest/904/E
来源:牛客网
DongDong数颜色
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
DongDong是个喜欢数颜色的女孩子,她已经熟练地掌握了在序列上数颜色的操作,现在她开始学习如何在树上数颜色,现在给定一个n个点,n-1条边的树形图(视1号店为根),每个点有一个颜色,每次询问以x为根的子树中有多少种不同的颜色,DongDong轻松地解决了这个问题,但她想考考会编程的你。
输入描述:
第一行两个整数n,m
第二行n个整数,表示每个点的颜色
接下来n-1行每行u,v,表示存在一条从u到v的双向边(保证最终图形是树形图)
2<=n<=100000,1<=m,color<=n,
输出描述:
共m行:每行输出相应询问的答案
示例1
输入
复制
4 3
1 1 2 3
1 2
2 3
1 4
1
2
4
输出
复制
3
2
1
思路:
我们知道一个节点的为根的子树节点在树的dfs序中是一个连续的区间,且区间的长度就是子树大小,那么我们可以一次dfs维护出
1、 以i节点为根的子树大小
2、 dfs序中第i个是哪个节点。
3、 第i个节点在dfs序中的位置。
然后我们可以把问题转化为常见的区间询问的问题,我们可以用莫队算法离线做。
细节见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 100010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll ans[maxn];
ll Ans=0ll;
int l=0;
int r=0;
struct node
{
int l,r,id;
}a[maxn];
int pos[maxn];
int n,m;
int len;
bool cmp(node aa,node bb)
{
if(pos[aa.l]==pos[bb.l])
{
return aa.r<bb.r;
}else
{
return pos[aa.l]<pos[bb.l];
}
}
int col[maxn];
int flag[maxn];
int wid[maxn];
void add(int x)
{
if(!flag[col[wid[x]]])
{
Ans++;
}
flag[col[wid[x]]]++;
}
void del(int x)
{
if(1==flag[col[wid[x]]])
{
Ans--;
}
flag[col[wid[x]]]--;
}
std::vector<int> son[maxn];
int S[maxn];
int tot=1;
int info[maxn];
void dfs(int x,int pre)
{
S[x]=1ll;
info[x]=tot;
wid[tot++]=x; // 保存dfs序的第i个位置是哪个节点。
for(auto y:son[x])
{
if(y!=pre)
{
dfs(y,x);
S[x]+=S[y];
}
}
}
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gg(n);gg(m);
len=(int)(sqrt(n));
repd(i,1,n)
{
gg(col[i]);
}
int u,v;
repd(i,1,n-1)
{
gg(u);
gg(v);
son[v].pb(u);
son[u].push_back(v);
}
dfs(1,-1);
repd(i,1,m)
{
gg(a[i].l);
int temp=S[a[i].l];// 以a[i].l 为根的子树大小。
a[i].l=info[a[i].l]; // a[i].l 在dfs序中的位置。
a[i].r=a[i].l+temp-1; // 询问区间 右端点 在dfs序中的位置。
a[i].id=i;
pos[i]=i/len; // 莫队分块的部分。
}
sort(a+1,a+1+m,cmp);
repd(i,1,m)
{
while(l>a[i].l)
{
l--;
add(l);
}
while(r<a[i].r)
{
r++;
add(r);
}
while(l<a[i].l)
{
del(l);
l++;
}
while(r>a[i].r)
{
del(r);
r--;
}
ans[a[i].id]=Ans;
}
repd(i,1,m)
{
printf("%lld\n",ans[i]);
}
return 0;
}
inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
牛客练习赛47 DongDong数颜色 (莫队算法)的更多相关文章
- [BZOJ2120]数颜色(莫队算法)
Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜 ...
- 牛客练习赛47 E DongDong数颜色 (树状数组维护区间元素种类数)
链接:https://ac.nowcoder.com/acm/contest/904/E 来源:牛客网 DongDong数颜色 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 5242 ...
- 牛客练习赛47 E DongDong数颜色 (树上启发式合并)
链接:https://ac.nowcoder.com/acm/contest/904/E 来源:牛客网 DongDong数颜色 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 5242 ...
- 牛客练习赛47 D DongDong坐飞机 (分层最短路)
链接:https://ac.nowcoder.com/acm/contest/904/D 来源:牛客网 DongDong坐飞机 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 5242 ...
- 牛客练习赛47 A DongDong破密码 (异或性质,递推)
链接:https://ac.nowcoder.com/acm/contest/904/A 来源:牛客网 DongDong破密码 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1310 ...
- bzoj2120 数颜色 莫队 带修改
[bzoj2120]数颜色 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔 ...
- bzoj2120: 数颜色 [莫队][分块]
Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜 ...
- BZOJ2120 数颜色 莫队 带修莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html 题目传送门 - BZOJ2120 题意 给定一个长度为 $n$ 的序列 $a$ ,有 ...
- 牛客练习赛31A 地、颜色、魔法(搜索+二维数组一维表示)
红色来源于山脉,象征着狂躁.愤怒.混乱,血雨腥风,电光火石. 蓝色来源于海岛,象征着控制.幻觉.诡计,运筹帷幄,谋定后动. 绿色来源于树林,象征着生命.蛮力.成长,横冲直撞,生生不息. 黑色来源于沼泽 ...
随机推荐
- ras 加密及解密
rsa 对数据进行加密和解密 #!/usr/bin/env python # coding=utf-8 """ pip3 install rsa "" ...
- Node.js的事件轮询Event Loop原理
Node.js的事件轮询Event Loop原理解释 事件轮询主要是针对事件队列进行轮询,事件生产者将事件排队放入队列中,队列另外一端有一个线程称为事件消费者会不断查询队列中是否有事件,如果有事件,就 ...
- POJ 1182-食物链 [并查集] 《挑战程序设计竞赛》2.4
Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...
- springMVC入门配置案例
1.spring的jar包下载 进入http://repo.springsource.org/libs-release-local/,然后依次点击org/-->springframework-- ...
- SQLserver本地数据库开发
远程端数据库中生成脚本 注意 远程端的数据库 是中文版的还是英文版的,一般我们装的是英文版的, 如果远程端数据库是中文版的,那么我们本地的是英文版,在生成的脚本那需要修改,同时去除相应的路劲代码. 修 ...
- SqlServer:SqlServer(存储过程动态表查询(取消返回值),事务处理,批量还原sqlserver备份,强制删除被占用的数据库)
1.存储过程动态表查询 USE [NETWORKING_AUDIT] GO /****** Object: StoredProcedure [dbo].[impConfigInfo] Script D ...
- 利用python将excel数据解析成json格式
利用python将excel数据解析成json格式 转成json方便项目中用post请求推送数据自定义数据,也方便测试: import xlrdimport jsonimport requests d ...
- VM虚拟机网络设置
两台PC安装了虚拟机和XP,采用“桥接”模式,设置了两个虚拟机的地址为同网段.但发现飞Q可以联通,数据库无法连接,且ping不通. 解决: (1)将防火墙关闭. (2)通过“虚拟网络编辑器”将该网络桥 ...
- 【go进阶】一个简单的go服务器实现
光阴似箭,日月如梭,在昨天我终于拿到了自己忙活了半个月的工资. 据说在7月25日有一颗小行星掠过地球,如果真的撞上来,估计31号我就不是乐呵呵的了,应该是直接没了. 如下的代码运行起来就是一个微型go ...
- [转帖]浪潮信息最大供应商英特尔(Intel):2018 年采购额 145.76 亿元
浪潮信息最大供应商英特尔(Intel):2018 年采购额 145.76 亿元 https://t.cj.sina.com.cn/articles/view/3172142827/bd130eeb01 ...