HDU5420 : Victor and Proposition
以深度建立线段树,线段树父亲节点向儿子节点连边,然后用线段树合并可以得到任何一个点子树的线段树,只需向对应节点的线段树中的$O(\log n)$个点连边即可。为了保证连边关系不发生混乱,线段树需要进行可持久化。
这样建图,点数和边数都是$O(n\log n)$级别的,再求出强连通分量,用排列组合求出答案即可。
#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstdlib>
const int N=100010,M=4000000,E=6000000;
int Case,n,i,x,y,f[M],d[N],root[N],fin[N],l[M],r[M],tot;
int gt[N],nxtt[N],vt[N],edt;
int ga[N],nxta[N],va[N],la[N],ra[N],eda;
int g[2][M],v[2][E],nxt[2][E],ed;
int q[M],t,vis[M],cnt[M];
long long ans;
void add(int x,int y){
vt[++edt]=y;
nxtt[edt]=gt[x];
gt[x]=edt;
}
void addask(int x,int y,int l,int r){
va[++eda]=y;
la[eda]=l;
ra[eda]=r<n?r:n;
nxta[eda]=ga[x];
ga[x]=eda;
}
void addedge(int x,int y){
if(!y)return;
v[0][++ed]=y;nxt[0][ed]=g[0][x];g[0][x]=ed;
v[1][ed]=x;nxt[1][ed]=g[1][y];g[1][y]=ed;
}
int merge(int x,int y,int a,int b){
if(!x)return y;
if(!y)return x;
int z=++tot;
if(a==b){
addedge(z,x);
addedge(z,y);
return z;
}
int mid=(a+b)>>1;
addedge(z,l[z]=merge(l[x],l[y],a,mid));
addedge(z,r[z]=merge(r[x],r[y],mid+1,b));
return z;
}
int build(int a,int b,int c){
int x=++tot;
if(a==b)return x;
int mid=(a+b)>>1;
if(c<=mid)addedge(x,l[x]=build(a,mid,c));else addedge(x,r[x]=build(mid+1,b,c));
return x;
}
void ask(int x,int a,int b,int c,int d,int p){
if(!x)return;
if(c<=a&&b<=d){
addedge(p,x);
return;
}
int mid=(a+b)>>1;
if(c<=mid&&l[x])ask(l[x],a,mid,c,d,p);
if(d>mid&&r[x])ask(r[x],mid+1,b,c,d,p);
}
void dfs(int x){
for(int i=gt[x];i;i=nxtt[i]){
dfs(vt[i]);
root[x]=merge(root[x],root[vt[i]],1,n);
}
for(int i=ga[x];i;i=nxta[i])ask(root[x],1,n,la[i],ra[i],va[i]);
}
void dfs1(int x){
vis[x]=1;
for(int i=g[0][x];i;i=nxt[0][i])if(!vis[v[0][i]])dfs1(v[0][i]);
q[++t]=x;
}
void dfs2(int x,int y){
vis[x]=0,f[x]=y;
for(int i=g[1][x];i;i=nxt[1][i])if(vis[v[1][i]])dfs2(v[1][i],y);
}
int main(){
scanf("%d",&Case);
while(Case--){
scanf("%d",&n);
for(i=2;i<=n;i++)scanf("%d",&f[i]),add(f[i],i);
for(i=1;i<=n;i++){
d[i]=d[f[i]]+1;
root[i]=build(1,n,d[i]);
fin[i]=tot;
}
for(i=1;i<=n;i++)scanf("%d%d",&x,&y),addask(x,fin[i],d[x],d[x]+y);
dfs(1);
for(i=1;i<=tot;i++)if(!vis[i])dfs1(i);
for(i=tot;i;i--)if(vis[q[i]])dfs2(q[i],q[i]);
for(i=1;i<=n;i++)cnt[f[fin[i]]]++;
for(i=1;i<=tot;i++)if(cnt[i])ans+=1LL*cnt[i]*(cnt[i]-1)/2;
printf("%I64d\n",ans);
for(i=1;i<=n;i++)gt[i]=ga[i]=f[i]=0;
for(i=1;i<=tot;i++){
l[i]=r[i]=vis[i]=cnt[i]=0;
g[0][i]=g[1][i]=0;
}
ans=tot=edt=eda=ed=t=0;
}
return 0;
}
HDU5420 : Victor and Proposition的更多相关文章
- HDU 5420 Victor and Proposition
Victor and Proposition Time Limit: 6000ms Memory Limit: 524288KB This problem will be judged on HDU. ...
- BestCoder Round #52 (div.1)
这周六BC和CF又差点打架,精力不够啊...结果打BC没起来,就看了一眼题跑了...今天早上补补吧,(因为今天晚上还要打UER= =) 先放官方题解: 1000 Victor and Machine ...
- CF460D Little Victor and Set (找规律)
D - Little Victor and Set Codeforces Round #262 (Div. 2) D D. Little Victor and Set time limit per t ...
- ACM: HDU 5418 Victor and World - Floyd算法+dp状态压缩
HDU 5418 Victor and World Time Limit:2000MS Memory Limit:131072KB 64bit IO Format:%I64d & ...
- HDU 5417 Victor and Machine
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5417 Problem Description Victor has a machine. When t ...
- Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件!
源:Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件! 2014年02月06日发布控件的重要更新版本: Victor 串口控件 1.5.0.2 版本 (包 ...
- Victor and World(spfa+状态压缩dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/ ...
- Codeforces 460D Little Victor and Set(看题解)
Little Victor and Set 其他都很好求, 只有k == 3的时候很难受.. 我们找到第一个不大于l的 t, 答案为 l, 3 * t, (3 * t) ^ l 感觉好像是对的, 感觉 ...
- 【HDU5421】Victor and String(回文树)
[HDU5421]Victor and String(回文树) 题面 Vjudge 大意: 你需要支持以下操作: 动态在前端插入一个字符 动态在后端插入一个字符 回答当前本质不同的回文串个数 回答当前 ...
随机推荐
- Linux之chkconfig命令
chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...
- c#:无法将 NULL 转换成“System.DateTime”,因为它是一种值类型
摘自:http://www.blogjava.net/parable-myth/archive/2010/09/30/333454.html 在C# 2.0里面的数据类型中,分为值类型和引用类型,引用 ...
- 20155220 2016-2017-2 《Java程序设计》第六周学习总结
20155220 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 第十章 输入输出 10.1 InputStream OutputStream 数据有来源与目 ...
- HDU 1229 还是A+B(A+B陶冶情操)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1229 解题报告:A+B #include<cstdio> int main() { int ...
- zookeeper笔记之基于zk实现分布式锁
一.分布式锁概述 Java中基于AQS框架提供了一系列的锁,但是当需要在集群中的多台机器上互斥执行一段代码或使用资源时Java提供的这种单机锁就没了用武之地,此时需要使用分布式锁协调它们.分布式锁有很 ...
- MongoDB 之 数据类型 最无聊! But 最有用! MongoDB - 3
MongoDB的新篇章开始啦 - 数据类型 https://www.cnblogs.com/xuzhaocai/p/8048177.html 一.MongoDB 之 丰富多彩的数据类型世界 首先我们要 ...
- FPGA学习笔记. 二分频和三分频
二分频和三分频 二分频:将输入频率CLK分为原来的 1/2 . 实现:在每次CLK的上升沿或下降沿将输出翻转. 三分频: 1/3占空比. 实现:可使用上升沿或下降沿计数生成输出.需要一个两位计数器. ...
- Java基础打包以及批处理命令运行
1.前期准备
- keepalived vrrp_script脚本不执行解决办法
首先打开日志观察: tail -f /var/log/messages 然后新开一个客户端重启keepalived , systemctl restart keepalived.service 看日志 ...
- os_mudule_docs
pydoc os Help on module os: NAME os - OS routines for Mac, NT, or Posix depending on what system we' ...