牛客练习赛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 地、颜色、魔法(搜索+二维数组一维表示)
红色来源于山脉,象征着狂躁.愤怒.混乱,血雨腥风,电光火石. 蓝色来源于海岛,象征着控制.幻觉.诡计,运筹帷幄,谋定后动. 绿色来源于树林,象征着生命.蛮力.成长,横冲直撞,生生不息. 黑色来源于沼泽 ...
随机推荐
- 集群中配置多台机器之间 SSH 免密码登录
集群中配置多台机器之间 SSH 免密码登录 问题描述 由于现在项目大多数由传统的单台机器部署,慢慢转变成多机器的集群化部署. 但是,这就涉及到机器间的 SSH 免密码互通问题. 当集群机器比较多的时候 ...
- SqlServer try catch 捕获触发器\存储过程异常,结合 transaction 事务
SoEasy~,贴上代码看所有 ALTER trigger [dbo].[tgr_SG_Gathering_update] on [dbo].[SG_Gathering] for update --更 ...
- pytorch基础问题
本文将自己在pytorch学习中遇见的各种问题整理起来,并且持续更新. 1:torch.Tensor和torch.tensor的区别 开始使用torch.tensor和torch.Tensor的时候发 ...
- 【MapReduce】二、MapReduce编程模型
通过前面的实例,可以基本了解MapReduce对于少量输入数据是如何工作的,但是MapReduce主要用于面向大规模数据集的并行计算.所以,还需要重点了解MapReduce的并行编程模型和运行机制 ...
- 企业邮箱 Webmail 通讯录导入 Outlook
企业邮箱暂不支持直接将通讯录同步至客户端软件,可以通过将通讯录在 Webmail 邮箱中导出,再导入所用软件的间接方法进行使用. 以Outlook 2010为例,如下详细导入通讯录步骤: 1.打开Ou ...
- 【Python开发】python集成开发环境IDE搭建
http://blog.csdn.net/pipisorry/article/details/39854707 使用的系统及软件 Ubuntu / windows Python 2.7 / pytho ...
- C语言中typedef,条件编译,结构体的说明
目录 typedef (类型别名) 条件编译 条件编译在头文件包含中的应用 结构体 使用结构体定义新的结构体变量 结构体成员的引用与赋值 结构体指针及其引用 typedef (类型别名) typede ...
- ASP.NET Core EFCore 之Code First
1.在.NET Core项目中使用Nuget引用包 Sql Server 请安装 Microsoft.EntityFrameworkCore.SqlServer 2.添加实体类 [Table(&quo ...
- 同sql server不同database间的数据访问
虽未经测试,但是应该是登陆名同时具有此2数据库访问权限啦. select * from [basename].dbo.[tablename] done.
- ssl安全验证
#ssl验证 r=requests.get('https://www.12306.cn',verify=False) print(r.content.decode('utf-8')) 结果: