[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算法的理论模型请参考自动控制理论,最早出现的是模 ...
随机推荐
- Power BI 报表服务器中的行级别安全性 (RLS)
在 Power BI Desktop 中定义角色和规则 你可以在 Power BI Desktop 中定义角色和规则. 发布到 Power BI 时,它还会发布角色定义. 若要定义安全角色,请执行以下 ...
- 【原创】大叔经验分享(73)scala akka actor
import java.util.concurrent.{ExecutorService, Executors, TimeUnit} import akka.actor.{Actor, ActorSy ...
- Vue-CLI项目汇总
Vue-CLI 项目搭建 Vue-CLI 项目在pycharm中配置 Vue-CLI 项目中相关操作 Vue-CLI项目中路由传参 Vue-CLI项目-vue-cookie与vue-cookies处理 ...
- VLC播放各种源
RTSP rtsp://admin:Shws1610@192.168.1.33:554/channel/01 UDP 播放推导本机上的udp流 : udp://@:1234 播放其他机器上的ud ...
- JQuery 判断复选框是否选中
$("input").attr("checked") == "checked" or "undefined" $(&qu ...
- 开关灯 ToggleButton
开关灯 ToggleButton textOn:对应true的时候:textOff:对应false的时候:给toggleButton设置监听器toggleButton.setOnCheckChange ...
- html页面嵌入php代码不显示内容
新建一个html文件,内容如下: <html> <head> <title>Example</title> </head> <body ...
- 使用cJSON解析JSON
cJSON获取数组元素的每个值 { "operType": 0x5, "field": ["time","matchRule&qu ...
- js页面重定向跳转代码总结(待续)
情形一:东八区,浏览器中文跳转 <script type="text/javascript"> var sLang = (navigator.language ? na ...
- POJ 1741 单次询问树上距离<=K的点对数 点分治
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; ; ], ...