【HDU】5420 Victor and Proposition【SCC+线段树】
来源:互联网 发布:营养配餐软件 编辑:程序博客网 时间:2024/06/06 03:35
题目链接:【HDU】5420 Victor and Proposition
#include <bits/stdc++.h>using namespace std ;typedef long long LL ;#define clr( a , x ) memset ( a , x , sizeof a )const int MAXN = 100005 ;const int MAXM = 4000005 ;const int MAXE = 20000005 ;struct Edge { int v , n ; Edge () {} Edge ( int v , int n ) : v ( v ) , n ( n ) {}} E[MAXE] ;struct Node { int l , r ;} T[MAXM] ;vector < int > G[MAXN] ;int H[MAXM] , cntE ;int root[MAXN] ;bool vis[MAXM] ;int dep[MAXN] ;int idx[MAXN] ;int dfn[MAXM] ;int low[MAXM] ;int num[MAXM] ;int scc[MAXM] ;int scc_cnt ;int dfs_idx ;int S[MAXM] ;int top ;int cur ;int n ;void init () { top = 0 ; cur = 1 ; cntE = 0 ; scc_cnt = 0 ; dfs_idx = 0 ; clr ( H , -1 ) ; clr ( dfn , 0 ) ; clr ( scc , 0 ) ; clr ( vis , 0 ) ;}void addedge ( int u , int v ) { E[cntE] = Edge ( v , H[u] ) ; H[u] = cntE ++ ;}int newnode () { T[cur].l = T[cur].r = 0 ; return cur ++ ;}int add ( int x , int l , int r ) { int o = newnode () ; if ( l == r ) vis[idx[x] = o] = 1 ; else { int m = l + r >> 1 ; if ( dep[x] <= m ) addedge ( o , T[o].l = add ( x , l , m ) ) ; else addedge ( o , T[o].r = add ( x , m + 1 , r ) ) ; } return o ;}int merge ( int x , int y ) { if ( !x ) return y ; if ( !y ) return x ; int o = newnode () ; addedge ( o , x ) ; addedge ( o , y ) ; if ( T[x].l || T[y].l ) T[o].l = merge ( T[x].l , T[y].l ) ; if ( T[x].r || T[y].r ) T[o].r = merge ( T[x].r , T[y].r ) ; if ( T[o].l ) addedge ( o , T[o].l ) ; if ( T[o].r ) addedge ( o , T[o].r ) ; return o ;}int dfs ( int u ) { root[u] = add ( u , 1 , n ) ; for ( int i = 0 ; i < G[u].size () ; ++ i ) { dep[G[u][i]] = dep[u] + 1 ; root[u] = merge ( root[u] , dfs ( G[u][i] ) ) ; } return root[u] ;}void update ( int L , int R , int v , int o , int l , int r ) { if ( L <= l && r <= R ) { addedge ( v , o ) ; return ; } int m = l + r >> 1 ; if ( L <= m && T[o].l ) update ( L , R , v , T[o].l , l , m ) ; if ( m < R && T[o].r ) update ( L , R , v , T[o].r , m + 1 , r ) ;}int tarjan ( int u ) { dfn[u] = low[u] = ++ dfs_idx ; S[top ++] = u ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( !dfn[v] ) low[u] = min ( low[u] , tarjan ( v ) ) ; else if ( !scc[v] ) low[u] = min ( low[u] , dfn[v] ) ; } if ( low[u] == dfn[u] ) { num[++ scc_cnt] = 0 ; do { scc[S[-- top]] = scc_cnt ; if ( vis[S[top]] ) ++ num[scc_cnt] ; } while ( S[top] != u ) ; } return low[u] ;}void solve () { int x , y ; init () ; scanf ( "%d" , &n ) ; for ( int i = 1 ; i <= n ; ++ i ) { G[i].clear () ; } for ( int i = 2 ; i <= n ; ++ i ) { scanf ( "%d" , &x ) ; G[x].push_back ( i ) ; } dep[1] = 1 ; dfs ( 1 ) ; for ( int i = 1 ; i <= n ; ++ i ) { scanf ( "%d%d" , &x , &y ) ; update ( dep[x] , min ( dep[x] + y , n ) , idx[i] , root[x] , 1 , n ) ; } for ( int i = 1 ; i <= n ; ++ i ) if ( !dfn[i] ) { tarjan ( i ) ; } LL ans = 0 ; for ( int i = 1 ; i <= scc_cnt ; ++ i ) { ans += 1LL * num[i] * ( num[i] - 1 ) / 2 ; } printf ( "%lld\n" , ans ) ;}int main () { int T ; scanf ( "%d" , &T ) ; for ( int i = 1 ; i <= T ; ++ i ) { solve () ; } return 0 ;}
0 0
- 【HDU】5420 Victor and Proposition【SCC+线段树】
- hdu 5420 Victor and Proposition 线段树建图+强连通分量
- hdu 5420 Victor and Proposition(强连通+线段树建图)
- hdu 5419 Victor and Toys 线段树成段更新
- hdu 5417 Victor and Machine
- hdu 5417 Victor and Machine
- HDU 5417 Victor and Machine
- HDU-5417Victor and Machine
- hdu 5417 Victor and Machine
- hdu 5419 Victor and Toys
- hdu 5417 Victor and Machine
- hdu 5418 Victor and World
- hdu 5418 Victor and World
- hdu 5417 Victor and Machine
- HDU 5419 Victor and Toys
- HDU 5421 Victor and String
- HDU 5421 Victor and String(回文树)
- hdu 5418 Victor and World 状压DP
- set删除某位置元素
- Eclipse设置背景色、字体大小
- NSTimer 使用进阶
- 消息队列、OSS常用操作封装
- C# List.sort排序详解(多权重,升序降序)
- 【HDU】5420 Victor and Proposition【SCC+线段树】
- Struts2开发指南
- TensorFlow文档索引
- JavaScript 标签云
- jQuery.extend 函数详解
- Camel In Action 第四章 Camel中bean的使用
- view的模糊背景
- javascript字符串分割为数组
- java设计模式之代理模式(一)