以深度建立线段树,线段树父亲节点向儿子节点连边,然后用线段树合并可以得到任何一个点子树的线段树,只需向对应节点的线段树中的$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的更多相关文章

  1. HDU 5420 Victor and Proposition

    Victor and Proposition Time Limit: 6000ms Memory Limit: 524288KB This problem will be judged on HDU. ...

  2. BestCoder Round #52 (div.1)

    这周六BC和CF又差点打架,精力不够啊...结果打BC没起来,就看了一眼题跑了...今天早上补补吧,(因为今天晚上还要打UER= =) 先放官方题解: 1000 Victor and Machine ...

  3. 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 ...

  4. ACM: HDU 5418 Victor and World - Floyd算法+dp状态压缩

    HDU 5418 Victor and World Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%I64d & ...

  5. HDU 5417 Victor and Machine

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5417 Problem Description Victor has a machine. When t ...

  6. Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件!

    源:Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件! 2014年02月06日发布控件的重要更新版本: Victor 串口控件 1.5.0.2 版本 (包 ...

  7. Victor and World(spfa+状态压缩dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/ ...

  8. Codeforces 460D Little Victor and Set(看题解)

    Little Victor and Set 其他都很好求, 只有k == 3的时候很难受.. 我们找到第一个不大于l的 t, 答案为 l, 3 * t, (3 * t) ^ l 感觉好像是对的, 感觉 ...

  9. 【HDU5421】Victor and String(回文树)

    [HDU5421]Victor and String(回文树) 题面 Vjudge 大意: 你需要支持以下操作: 动态在前端插入一个字符 动态在后端插入一个字符 回答当前本质不同的回文串个数 回答当前 ...

随机推荐

  1. bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash

    http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...

  2. python学习笔记6--mockserver

    一.mockserver的应用 有时候测试我们需要调用一些三方接口或者未开发完成的接口,完成我们的业务流程测试,但是这时候可能我们只知道接口返回值,接口并没有完全开发完成或可以让我们任意调用,这时候就 ...

  3. javascript数组赋值操作

    最近在司徒正美的<javascript框架设计>,在里面发现了一个段代码 ...... var _len = arr1.length; while (_len) { arr2[--_len ...

  4. XMPP用户登录

    CHENYILONG Blog XMPP用户登录 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilon ...

  5. 第9月第26天 pairs和ipairs cocos2dx 动画

    1. a={ ip = "127.0.0.1", port = 6789 } for i,v in pairs(a) do print(i,v) end a={1} for i,v ...

  6. 第6月第19天 lua动态链接库(luaopen_*函数的使用) skynet

    1. 给这个测试库取名为dylib,它包含一个函数add.lua中这样使用: local dylib = require "dylib.test"    local c = dyl ...

  7. 【ARTS】01_08_左耳听风-20181231~20190106

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

  8. MVC常用特性使用

    简介 在以前的文章中,我和大家讨论如何用SingalR和数据库通知来完成一个消息监控应用. 在上一篇文章中,我介绍了如何在MVC中对MongoDB进行CRUD操作. 今天,我将继续介绍一些在开发中非常 ...

  9. python psutil监控系统资源【转】

    通过 运用 Python 第三方 系统 基础 模块, 可以 轻松 获取 服务 关键 运营 指标 数据,包括 Linux 基本 性能. 块 设备. 网卡 接口. 系统 信息. 网络 地址 库 等 信息. ...

  10. MYSQL数据库链接层- SUMMER-SQL

    2015年3月31日 18:27:34 最后编辑: 2016年4月17日 00:22:00 星期日 最后编辑: 2018-4-25 16:58:44 星期三 最新代码: https://gitee.c ...