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 大意: 你需要支持以下操作: 动态在前端插入一个字符 动态在后端插入一个字符 回答当前本质不同的回文串个数 回答当前 ...
随机推荐
- 那些年的 网络通信之 UDP 数据报包传输---
下面是 一个多线程,基于 UDP 用户数据报包 协议 的 控制台聊天小程序 import java.io.*; import java.net.*; class Send implements Run ...
- Spring Cloud (十三) Zuul:静态路由、静态过滤器与动态路由的实现
前言 本文起笔于2018-06-26周二,接了一个这周要完成的开发任务,需要先等其他人的接口,可能更新的会慢一些,还望大家见谅.这篇博客我们主要讲Spring Cloud Zuul.项目地址:我的gi ...
- html5 canvas 奇怪的形状水平渐变(因为大多数的之前的文章把基础都打过了,所以开始写的快了,如果有不明白的,可以回顾下之前的)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 关于aspx.designer.cs
.aspx文件..aspx.cs文件和.aspx.designer.cs的一些说明 .aspx文件:(页面)书写页面代码.存储的是页面design代码.只是放各个控件的代码,处理代码一般放在.cs文件 ...
- es6笔记(3.1)三个点的“...”的作用
展开运算符(spread operator) ES6中"..."的作用之一是,展开运算符. 顾名思义,它的作用是把某些结合数据展开. 在Array.Object.Set和Map上都 ...
- Java笔记之java.lang.String#trim
String的trim()方法是使用频率频率很高的一个方法,直到不久前我不确定trim去除两端的空白符时对换行符是怎么处理的点进去看了下源码的实现,才发现String#trim的实现跟我想像的完全不一 ...
- hdu GuGuFishtion 6390 数论 欧拉函数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=6390 直接开始证明: 我们设…………………………………….....…...............………… ...
- mysql Keepalived 实践
Keepalived 是一种高性能的服务器高可用或热备解决方案,Keepalived可以用来防止服务器单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构的不可用)的发生,通过配合Nginx可 ...
- update-rc.d使用
在Linux系统下,一个Services的启动.停止以及重启通常是通过/etc/init.d目录下的脚本来控制的.然而,在启动或改变运行级别时,是在/etc/rcX.d中来搜索脚本.其中X是运行级别的 ...
- mac lsof使用查看端口
安装 brew install lsof 在Mac OS系统中,无法使用netstat来查看端口占用情况,可以使用lsof来代替,这种方式在Linux下也适用. sudo lsof -nP -iTCP ...