HDU 5420 Victor and Proposition
2015-10-12 13:21
501 查看
Victor and Proposition
Time Limit: 6000msMemory Limit: 524288KB
This problem will be judged on HDU. Original ID: 5420
64-bit integer IO format: %I64d Java class name: Main
At the very beginning, Victor has a proposition, then this proposition procudes many propositions. Then every proposition procudes more propositions...... Finally there are n propositions. These propositions can be regarded as a tree whose root is 1.
We assume that the first proposition, whose number is 1, belongs to the 0-th generation, and those propositions produced by the x-th generation belong to the x+1-th generation. We also assume that all of the propositions in the x-th generation are in level x. Specially, Victor has discovered that the proposition whose number is i can infer the proposition whose number is xi and all of the propositions in xi's subtree, whose levels are not greater than xi's level + di.
Notice : a is b's father does not show that either a can infer b or b can infer a.
Now please determine the number of such ordered pairs (i,j), that 1≤i<j≤n, the proposition i can infer the proposition j, and the proposition j can also infer the proposition i.
Input
The first line of the input contains an integer T, denoting the number of test cases.
In every test case, there is an integer n in the first line, denoting the number of the propositions.
The second line contains n−1 integers, the i-th integer fi+1(fi<i) denotes that the proposition i+1 is produced by the proposition fi+1.
Then there are n lines, the i-th line contains two integers xi and di.
1≤T≤5.
2≤n≤100000.
0≤di<n.
Output
Your program should print T lines : the i-th of these should contain a single integer, denoting the number of such ordered pairs (i,j).
Sample Input
1
4
1 2 1
2 1
1 0
4 0
2 0
Sample Output
6
Source
BestCoder Round #52 (div.2)
解题:线段树优化建图,妙哉,内存开得好凶残,吓呆本宝宝了
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int INF = 0x3f3f3f3f; const int maxn = 2000010; struct arc { int to,next; arc(int x = 0,int y = -1) { to = x; next = y; } } e[(100000+1000)*20*8]; int head[maxn],L[maxn],R[maxn],tot,clk; int dep[maxn],hs[maxn],st[maxn],n; vector<pii>order[maxn]; void add(int u,int v) { e[tot] = arc(v,head[u]); head[u] = tot++; } void init() { tot = 0; memset(head,-1,sizeof head); } void dfs(int u,int depth) { hs[L[u] = ++clk] = u; dep[u] = depth; for(int i = head[u]; ~i; i = e[i].next) dfs(e[i].to,depth + 1); R[u] = clk; } void build(int L,int R,int v) { order[v].resize(R - L + 1); if(L == R) { st[v] = ++n; order[v][0] = pii(dep[hs[L]],hs[L]); add(n,hs[L]); return; } int mid = (L + R)>>1; build(L,mid,v<<1); build(mid + 1,R,v<<1|1); st[v] = n + 1; merge(order[v<<1].begin(),order[v<<1].end(),order[v<<1|1].begin(),order[v<<1|1].end(),order[v].begin()); for(int i = 1; i <= R - L; ++i) add(n + i + 1, n + i); for(int i = 0; i <= R - L; ++i) add(n + i + 1,order[v][i].second); n += R - L + 1; } void connect(int L,int R,int lt,int rt,int u,int d,int v) { if(lt <= L && rt >= R) { int pos = lower_bound(order[v].begin(),order[v].end(),pii(d,INF)) - order[v].begin() - 1; if(~pos) add(u,st[v] + pos); return; } int mid = (L + R)>>1; if(lt <= mid) connect(L,mid,lt,rt,u,d,v<<1); if(rt > mid) connect(mid + 1,R,lt,rt,u,d,v<<1|1); } int dfn[maxn],low[maxn],cnt[maxn],scc,ct; bool instack[maxn]; stack<int>stk; void tarjan(int u) { dfn[u] = low[u] = ++ct; instack[u] = true; stk.push(u); for(int i = head[u]; ~i; i = e[i].next) { if(!dfn[e[i].to]) { tarjan(e[i].to); low[u] = min(low[u],low[e[i].to]); } else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]); } if(low[u] == dfn[u]) { int v; cnt[++scc] = 0; do { instack[v = stk.top()] = false; stk.pop(); cnt[scc] += (v <= clk); } while(v != u); } } int main() { int kase,u,v; scanf("%d",&kase); while(kase--) { scanf("%d",&n); init(); clk = scc = ct = 0; memset(dfn,0,sizeof dfn); memset(instack,false,sizeof instack); for(int i = 2; i <= n; ++i) { scanf("%d",&u); add(u,i); } dfs(1,0); init(); build(1,clk,1); for(int i = 1; i <= clk; ++i) { scanf("%d%d",&u,&v); connect(1,clk,L[u],R[u],i,dep[u] + v,1); } for(int i = 1; i <= n; ++i) if(!dfn[i]) tarjan(i); LL ret = 0; for(int i = 1; i <= scc; ++i) ret += (LL)cnt[i]*(cnt[i]-1)/2; printf("%I64d\n",ret); } return 0; }
View Code
相关文章推荐
- Linux 常用命令(转)
- inittab文件内容解析
- nginx 的编译参数详解
- KeyStone 架构DSP C66x系列高端研发平台
- CentOS下MySQL数据库调优
- Linux改变进程优先级的nice及renice命令
- 2015年网站设计我们将看到这十大趋势
- ksh 命令分隔符
- opencv 傅里叶变换与反变换
- CentOS下MySQL安装后配置和设置
- Linux-CentOS 用户名 不在 sudoers文件中,此事将被报告
- hadoop安装问题
- 014-案例开发.Storm计算网站PV
- 正则表达式技术实例
- VMware Workstation 共享磁盘和Linux的UDEV使用
- Linux 下 YUM 安装 NGiNX
- Linux文件删除原理
- opencv学习笔记(十一)——图像的载入,显示和输出到文件
- VS2012配置OpenGL
- Linux 命令 - jobs: 显示后台作业的状态信息