题目背景

影魔,奈文摩尔,据说有着一个诗人的灵魂。事实上,他吞噬的诗人灵魂早已成千上万。
千百年来,他收集了各式各样的灵魂,包括诗人、牧师、帝王、乞丐、奴隶、罪人,当然,还有英雄。
每一个灵魂,都有着自己的战斗力,而影魔,靠这些战斗力提升自己的攻击。


题目传送门(内部题42)


输入格式

第一行两个数$n,m$。
第二行$n$个数,第$i$个数即第$i$个灵魂结点的灵魂种类$c_i$。
第三行$n-1$个数,第$i$个数表示$i+1$号灵魂结点的父亲结点。
接下来$m$行,每行两个数$u,d$,表示一组询问。


输出格式

一共$m$行,每一行一个数表示对应询问的答案。


样例

样例输入:

5 5
1 3 3 2 2
1 1 3 3
1 0
1 3
1 2
2 1
3 2

样例输出:

1
3
3
1
2


数据范围与提示

对于$30\%$的数据,$n,m\leqslant 1,000$
对于另外$10\%$的数据,保证数据随机
对于另外$20\%$的数据,每次询问满足$d={10}^9$
对于另外$20\%$的数据,满足$n,m\leqslant 20,000$
对于$100\%$的数据,满足$n,m\leqslant 100,000,c_i,n\leqslant n$


题解

我好像又没打正解……

我的思路就是,现将问题离线,然后$DFS$,每次合并儿子的,用线段树合并实现,用树状数组优化。

听着简单,但是实现起来还是蛮难的,调了好久……

不知道有什么好说的了,精髓还是在代码里。

时间复杂度:$\Theta(n\log^2 n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to;}e[100000];
int head[100001],cnt;
int n,m;
int c[100001],f[100001];
int trs[400001],depth[100001];
int ans[100001];
vector<pair<int,int> > question[100001];
void add(int x,int y)
{e[++cnt].nxt=head[x];e[cnt].to=y;head[x]=cnt;
}
int lowbit(int x){return x&-x;}
void change(int x,int w){for(int i=x;i<=n;i+=lowbit(i))trs[i]+=w;}
int ask(int x){int res=0;for(int i=x;i;i-=lowbit(i))res+=trs[i];return res;}
int tr[4000001],ls[4000001],rs[4000001];
int root[200001],tot;
void insert(int &x,int k,int fl,int l,int r)
{if(!x)x=++tot;if(l==r){tr[x]=fl;change(fl,1);return;}int mid=(l+r)>>1;if(k<=mid)insert(ls[x],k,fl,l,mid);else insert(rs[x],k,fl,mid+1,r);
}
void merge(int &x,int fl,int l,int r)
{if(!fl)return;if(!x){x=fl;return;}if(l==r){change(max(tr[x],tr[fl]),-1);tr[x]=min(tr[x],tr[fl]);return;}int mid=(l+r)>>1;merge(ls[x],ls[fl],l,mid);merge(rs[x],rs[fl],mid+1,r);
}
void dfs(int x)
{for(int i=0;i<question[x].size();i++)ans[question[x][i].first]-=ask(min(depth[x]+question[x][i].second,n))-ask(depth[x]-1);insert(root[x],c[x],depth[x],0,n);for(int i=head[x];i;i=e[i].nxt){depth[e[i].to]=depth[x]+1;dfs(e[i].to);merge(root[x],root[e[i].to],0,n);}for(int i=0;i<question[x].size();i++)ans[question[x][i].first]+=ask(min(depth[x]+question[x][i].second,n))-ask(depth[x]-1);
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&c[i]);for(int i=2;i<=n;i++){scanf("%d",&f[i]);add(f[i],i);}for(int i=1;i<=m;i++){int u,d;scanf("%d%d",&u,&d);question[u].push_back(make_pair(i,d));}depth[1]=1;dfs(1);for(int i=1;i<=m;i++)printf("%d\n",ans[i]);return 0;
}


rp++

转载于:https://www.cnblogs.com/wzc521/p/11524336.html

[CSP-S模拟测试]:影魔(树状数组+线段树合并)相关推荐

  1. D-query SPOJ - DQUERY(求区间不同数的个数)(树状数组||线段树+离散)(主席树+在线)

    English Vietnamese Given a sequence of n numbers a1, a2, -, an and a number of d-queries. A d-query ...

  2. HDU 1556 前缀和 树状数组 线段树

    解法一: a[i]表示以 i作为起点,对 i-n的气球全部上色的次数  对(start,end)区间上色 ++a[start] --a[end+1]抵消掉 end+1-n的部分 问题转换为求 a的前缀 ...

  3. jzoj3854-分组【树状数组,线段树】

    正题 题目链接:https://jzoj.net/senior/#contest/show/2990/2 题目大意 一个小队满足要求 队长的地位最高 所有队员和队长的年龄差不超过kkk 给出nnn个人 ...

  4. 模板三连击:树状数组+线段树+主席树

    没事儿干,复习模板...... 1.树状数组 本来不想写这个的,但是反正就几分钟就打完了,所以就写了,水AC数. 洛谷 P3374 [模板]树状数组 1 1 #include<cstdio> ...

  5. 51nod 1680区间求和 (dp+树状数组/线段树)

    不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...

  6. CCF201709-5 除法(100分)【树状数组+线段树】

    试题编号: 201709-5 试题名称: 除法 时间限制: 10.0s 内存限制: 256.0MB 问题描述: 问题描述 小葱喜欢除法,所以他给了你N个数a1, a2, ⋯, aN,并且希望你执行M次 ...

  7. POJ2182 HDU2711 Lost Cows【树状数组+线段树】

    Lost Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17113 Accepted: 10664 Descripti ...

  8. P2357 守墓人(树状数组/线段树)

    题目描述 在一个荒凉的墓地上 有一个令人尊敬的守墓人, 他看守的墓地从来 没有被盗过, 所以人们很放心的把自己的先人的墓 安顿在他那 守墓人能看好这片墓地是必然而不是偶然..... 因为....守墓人 ...

  9. 差分+树状数组 线段树【P2357】 守墓人

    题目描述-->p2357 守墓人 敲了一遍线段树,水过. 树状数组分析 主要思路: 差分 简单介绍一下差分(详细概念太麻烦,看下面. 给定一个数组 7 8 6 5 1 8 18 20 35 // ...

最新文章

  1. 如何关闭vue项目中eslint的校验
  2. Android MVVM 架构应用实现
  3. Altera FPGA管脚弱上拉电阻详细设置方法
  4. spark从入门到精通spark内存管理详解- 堆内堆外内存管理
  5. 如意报表插件如何安装_Google Chrome浏览器如何安装插件应用
  6. 命令行下的mysql的基本操作
  7. 2017 JavaScript 调查报告概述
  8. openshift 3 mysql_最新OpenShift免费空间申请与使用教程-1G内存1G空间支持PHP和MysqL
  9. JavaScript中带示例的字符串search()方法
  10. mysql 占用swap_查看swap占用情况
  11. 机器学习中的Bias,Error,Variance的区别
  12. 神经网络训练输入数据并行化
  13. airpods pro是按压还是触摸_为什么都不推荐购买AirPods Pro,看完这6个缺陷,你就明白了...
  14. 【数学建模】基于matlab无线可充电传感器网络充电路线规划【含Matlab源码 750期】
  15. 产品经理面试题目转载
  16. asymptotic (infinite-training-sample)
  17. java分布式框架-JDF
  18. 【VUE】前端搜索引擎优化seo
  19. oracle remap schema,oracle 10g DATA PUMP 的REMAP_SCHEMA和REMAP_TABLESPACE的功能
  20. javaScript 561. 数组拆分 I

热门文章

  1. 树莓派魔镜MagicMirror —— 4 系统安装与配置
  2. Linux如何打开cp2k,centos7安装并行版cp2k6.1-POPT
  3. Xposed插件开发手册(1): Xposed框架的安装
  4. 重装系统重启后计算机属性无法打开,Win7系统计算机属性窗口无法打开的两种参考方法...
  5. 经典的soo单点登录实现
  6. 跑在SOA上的出版社
  7. 关于云计算的 7 大误区
  8. 解读BLM业务设计中的战略控制点
  9. 我对读计算机软件专业硕士的几点看法
  10. 从服务上下载下的日志文件,用UltraEdit打开时中文是乱码解决方法