[CSP-S模拟测试]:射手座之日(dsu on tree)
题目传送门(内部题103)
输入格式
第一行一个数$n$,表示结点的个数。
第二行$n–1$个数,第$i$个数是$p[i+1]$。$p[i]$表示结点$i$的父亲是$p[i]$。数据保证$p[i]<i$。
第三行$n$个数,$a[1],a[2],...,a[n]$,表示关卡表。数据保证这是一个排列。
第四行$n$个数,$x[1],x[2],...,x[n]$,表示结点的权值。
输出格式
输出一个数表示答案。即对于所有可能的回合,你们能获得的总收益是多少。
数据范围与提示
对于$20\%$的数据,满足$n\leqslant 100$。
对于$40\%$的数据,满足$n\leqslant 2,000$。
对于$60\%$的数据,满足$n\leqslant 50,000$。
对于另外$20\%$的数据,排列$a[i]$是用如下的算法生成的:从一号点开始对树做$dfs$,到达一个节点的时候输出这个结点。
对于$100\%$的数据,满足$1\leqslant n\leqslant 200,000,0\leqslant x[i]\leqslant 100,000,p[i]<i$,$a[i]$是一个排列。
题解
其实另外$20\%$的数据就是正解的一个引导。
显然对于这个部分分无非就是输出每一个点的子节点的$size$相互之间的乘积和乘上这个点的$x$值即可。
那么考虑正解。
用$dsu\ on\ tree$思想,每个节点继承儿子中最重的节点的信息,其他儿子暴力合并;用两个数组记录当前位置是否是一个极长区间的左(右)端点并记录另一个端点的位置,加入一个节点时尝试合并左右信息并统计合并后的方案数即可。
时间复杂度:$\Theta(n\log n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to;}e[200000];
int head[200001],cnt;
int n;
int a[200001],val[200001],size[200001],son[200001],l[200001],r[200001],vis[200001],dfn[200001],now;
long long ans;
void add(int x,int y)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void dfs(int x)
{
size[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
dfs(e[i].to);
size[x]+=size[e[i].to];
if(size[son[x]]<size[e[i].to])son[x]=e[i].to;
}
}
long long insert(int x)
{
vis[a[x]]=now;
if(vis[a[x]+1]!=now)l[a[x]+1]=r[a[x]+1]=0;
if(vis[a[x]-1]!=now)l[a[x]-1]=r[a[x]-1]=0;
long long L=l[a[x]-1],R=r[a[x]+1],len=l[a[x]-1]+r[a[x]+1]+1;
l[a[x]]=L+1;r[a[x]]=R+1;l[a[x]+R]=r[a[x]-L]=len;
return len*(len+1)/2-L*(L+1)/2-R*(R+1)/2;
}
long long ask(int x)
{
long long res=insert(x);
for(int i=head[x];i;i=e[i].nxt)
res+=ask(e[i].to);
return res;
}
int dfs(int x,int opt)
{
now=dfn[x]=x;
long long res=0,num=0,flag=0;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=son[x])res-=dfs(e[i].to,0);
if(son[x])
{
flag=dfs(son[x],1);
num+=flag;
now=dfn[x]=dfn[son[x]];
}
num+=insert(x);
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=son[x])num+=ask(e[i].to);
ans+=(res+num-flag)*val[x];
return num;
}
int main()
{
scanf("%d",&n);
for(int i=2;i<=n;i++){int x;scanf("%d",&x);add(x,i);}
for(int i=1;i<=n;i++){int x;scanf("%d",&x);a[x]=i;}
for(int i=1;i<=n;i++)scanf("%d",&val[i]);
dfs(1);
dfs(1,1);
printf("%lld",ans);
return 0;
}
rp++
[CSP-S模拟测试]:射手座之日(dsu on tree)的更多相关文章
- 联赛模拟测试10 C. 射手座之日
题目描述 分析 方法一(线段树) 线段树维护的是以当前节点为左端点的区间的贡献 而区间的右端点则会从 \(1\) 到 \(n\) 逐渐右移 当我们把右端点从 \(i-1\) 的位置扩展到 \(i\) ...
- csp-s模拟测试94
csp-s模拟测试94 一场简单题,打爆了.$T1$脑抽分解质因数准备分子分母消,想了半天发现$jb$互质直接上天,果断码了高精滚蛋.$T2$无脑手玩大样例,突然灵光一闪想到映射到前$K$大小的区间, ...
- [考试反思]1030csp-s模拟测试94:未知
排名也未知.第1或第5. 分数也未知,300或260. 人生真是大起大落... 啊啊啊啊啊我好感动啊竟然重测了一次----- 评测机怎么测怎么RE,本机怎么测怎么AC(任意编译指令,任意评测平台) 结 ...
- [CSP-S模拟测试94]题解
A.凉宫春日的忧郁 高精硬上似乎跑不过,其实可以都取个$log$.那么只需要比较$y\times log ^x$和$\sum \limits _{i=1}^y log^i$就好了. #include& ...
- Android单元测试与模拟测试详解
测试与基本规范 为什么需要测试? 为了稳定性,能够明确的了解是否正确的完成开发. 更加易于维护,能够在修改代码后保证功能不被破坏. 集成一些工具,规范开发规范,使得代码更加稳定( 如通过 phabri ...
- [开源]微信在线信息模拟测试工具(基于Senparc.Weixin.MP开发)
目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具 ...
- 安装nginx python uwsgi环境 以及模拟测试
uwsgi帮助文档: http://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/WSGIquickstart.html http://uwsgi-docs.re ...
- 利用Python中的mock库对Python代码进行模拟测试
这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下 ...
- 转 C#实现PID控制的模拟测试和曲线绘图
C#实现PID控制的模拟测试和曲线绘图 本文分两部分,一部分是讲PID算法的实现,另一部分是讲如何用动态的曲线绘制出PID运算的结果. 首先,PID算法的理论模型请参考自动控制理论,最早出现的是模 ...
随机推荐
- C#文本_文件夹操作
1我们常用的File类 可以用来对文件的一些操作 下面看代码. using System;using System.Collections.Generic;using System.IO;using ...
- idea2019 Tomcat9 Tomcat Localhost log 乱码
网上一顿搜索,基本没用,可能版本不一样. idea2019 tomcat9解决方案: 找到Tomcat的安装目录,进入conf目录 打开logging.properties 找到java.util.l ...
- 【opencv源码解析】 二、 cvtColor
这里以CV_BGR2YUV_I420来讲 1. opencv244 core.cpp void cv::cvtColor( InputArray _src, OutputArray _dst, int ...
- logback替换log4j
1.新建logback.xml放在src目录下(放在src下会自动加载,不需要再web.xml配置) 2.引入必要的jar包:
- plist文件的归档,解档
plist文件 plist的根Type只能是字典(NSDictionary)或者是数组(NSArray)所以归档时我们只能将数组或字典保存到plist文件中,但是NSString也能通过归档保存到pl ...
- SpringBoot-核心依赖说明
spring-boot-dependencies 一般用来放在父项目中,来声明依赖,子项目引入相关依赖而不需要指定版本号,好处就是解决依赖冲突,统一管理依赖版本号 利用pom的继承,一处声明,处处使用 ...
- 微服务之Nacos配置中心源码解析(二)
Nacos配置中心源码解析 源码入口 ConfigFactory.createConfigService ConfigService configService = NacosFactory.crea ...
- centos 7 安装 Git-2.23.0
Git是一个免费的开源 分布式版本控制系统,旨在快速高效地处理从小型到大型项目的所有内容. Git 易于学习,占地面积小,具有闪电般的快速性能. 它具有诸如Subversion,CVS,Perforc ...
- Linux系统安装常用开发软件
vim.jdk.tomcat.mysql 安装vim(命令模式=>编辑模式=>底行模式) [root@localhost ~]# yum install vim*结束后一直确认即可,键入y ...
- WiFi 6是否适合个人用户
5G已经被热炒得家喻户晓,但与其对标的WiFi新技术标准——Wi-Fi 6却可能有着更好的经济和技术前景,WiFi 6也称为802.11ax,比过去的Wi-Fi技术更好,速度更快能跟5G对标,连接性更 ...