当前位置:网站首页>2022年杭电多校第2场 1001 Static Query on Tree(树链剖分+哈希表差分
2022年杭电多校第2场 1001 Static Query on Tree(树链剖分+哈希表差分
2022-07-30 17:32:00 【NONE-C】
题目大意:
给定一棵根为1的树,给定点集A,B,C,能被A任意一个到达,B任意一个到达,且能达到C的任意一个的点的数量。
这是第二场多校,写完签到题,就开了1001。其实看懂题目之后,思路还是挺快就出现了,当时就给队友口胡了一种算法,如果能把C的子树染色,在把A,B每一个点到1的路径上的全部打上个标记,最后统计一下答案救过了。但是不知道该怎么操作,赛后看题解,树链剖分!
果然还是吃了没文化(数据结构)的亏,花了两天在恶补树剖,终于把这题给A了。
本来打算写线段树的,但是想到就只有三种颜色,用点小技巧就可以过了,少写线段树,代码立马缩减90行
#include<bits\stdc++.h>
using namespace std;
const int maxn=2e5+5;
#define ll long long
int n,m,na,nb,nc;
int sz[maxn],son[maxn],fa[maxn],top[maxn],cnt=0,nid[maxn],dep[maxn];
int a[maxn],b[maxn],c[maxn];
vector<int>e[maxn];
ll tr[maxn];
map<int,ll>add;
void dfs1(int s,int father)
{
fa[s]=father;
sz[s]=1,dep[s]=dep[father]+1;
for(auto to:e[s])
{
if(to==father)continue;
dfs1(to,s);
sz[s]+=sz[to];
if(sz[son[s]]<sz[to])son[s]=to;
}
}
void dfs2(int s,int t)
{
nid[s]=++cnt;top[s]=t;
if(!son[s])return ;
dfs2(son[s],t);
for(auto to:e[s])
{
if(to==fa[s]||to==son[s])continue;
dfs2(to,to);
}
}
void add_path(int u,int v,ll y)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
add[nid[top[u]]]+=y;add[nid[u]+1]-=y;
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
add[nid[u]]+=y;add[nid[v]+1]-=y;
}
void add_tree(int u,ll y)
{
add[nid[u]]+=y;
add[nid[u]+sz[u]-1+1]-=y;
}
const ll p1=1;
const ll p2=1e6;
const ll p3=1e12;
void solve()
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)nid[i]=0,e[i].clear(),top[i]=0,fa[i]=0,son[i]=0,sz[i]=0,tr[i]=0;
for(int i=2;i<=n;i++)
{
int u;
scanf("%d",&u);
e[u].push_back(i);
e[i].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
while(m--){
scanf("%d%d%d",&na,&nb,&nc);
for(int i=1;i<=na;i++)scanf("%d",&a[i]);
for(int i=1;i<=nb;i++)scanf("%d",&b[i]);
for(int i=1;i<=nc;i++)scanf("%d",&c[i]);
for(int i=1;i<=na;i++)add_path(1,a[i],(ll)p1);
for(int i=1;i<=nb;i++)add_path(1,b[i],(ll)p2);
for(int i=1;i<=nc;i++)add_tree(c[i],(ll)p3);
ll ans=0;int cnt=0,las=-1;
for(auto it:add){
ans+=it.second;
if(ans%p2>0&&(ans%p3)/p2>0&&ans/p3>0){
if(las==-1)las=it.first;}
else if(las!=-1)cnt+=(it.first-las),las=-1;
}
printf("%d\n",cnt);
add.clear();
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)solve();
return 0;
}
边栏推荐
- 【Cloud Store Announcement】Notice of Help Center Update on July 30
- Mongoose module
- 图卷积神经网络的数学原理——谱图理论和傅里叶变换初探
- 首发!阿里技术大牛最新耗时半个月整理出最全MySQL性能优化和高可用架构技术宝典,直接封神!
- 将 APACHE 日志解析到 SQL 数据库中
- 强烈推荐APP破解常用工具集合!
- Error EPERM operation not permitted, mkdir 'Dsoftwarenodejsnode_cache_cacach Two solutions
- 17.机器学习系统的设计
- 知识蒸馏1:基础原理讲解及yolov5项目实战介绍
- 数据预处理:离散特征编码方法
猜你喜欢

升级 MDK 5.37 后的问题处理: AC6编译选项, printf, 重启失效等
![Valid bracketed strings [greedy exercise]](/img/1c/5cefb53bc4aba54dd79b0cc9b09b0d.png)
Valid bracketed strings [greedy exercise]

JMeter Notes 4 | JMeter Interface Introduction

一篇文 带你搞懂,虚拟内存、内存分页、分段、段页式内存管理(超详细)

万华化学精细化工创新产品大会

JMeter笔记4 | JMeter界面介绍

论文阅读之《Underwater scene prior inspired deep underwater image and video Enhancement (UWCNN)》

C语言向MySQL插入数据

每日一题:两数之和

基于MATLAB的电力系统短路故障分析与仿真
随机推荐
Google earth engine如何实现我们时间列表的排列和选取
数据库系统原理与应用教程(068)—— MySQL 练习题:操作题 90-94(十二):DML 语句练习
数据库系统原理与应用教程(063)—— MySQL 练习题:操作题 39-50(七):SELECT 基本语法联系
顺通海关查验预约综合管理系统
首发!阿里技术大牛最新耗时半个月整理出最全MySQL性能优化和高可用架构技术宝典,直接封神!
C语言向MySQL插入数据
Moralis去中心化Web3应用开发教程
华为无线设备Mesh配置命令
SQLServer下载与安装
Test Management and Specification
中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030
数据库系统原理与应用教程(069)—— MySQL 练习题:操作题 95-100(十三):分组查询与聚合函数的使用
olap——入门ClickHouse
(17)[系统调用]追踪系统调用(0环)
高级语言垃圾回收思路和如何减少性能影响原理分析
Excel导入和导出
如何让 JOIN 跑得更快?
Prometheus 基本概念
知识蒸馏2:目标检测中的知识蒸馏
每日练习------生成13位条形, Ean-13码规则:第十三位数字是前十二位数字经过计算得到的校验码。
