生活随笔
收集整理的這篇文章主要介紹了
[SCOI2015]情报传递(主席树+lca)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
鏈接:https://ac.nowcoder.com/acm/problem/20570
來源:牛客網(wǎng)
輸出描述:
對于每個傳遞情報任務輸出一行,應包含兩個整數(shù),分別是參與傳遞情報的情報員個數(shù)和對該條情報構成威脅的情報員個數(shù)。
輸出的行數(shù)應等于傳遞情報任務的個數(shù),每行僅包含兩個整數(shù),用一個空格隔開。輸出不應包含多余的空行和空格。
示例1
輸入
復制
7
0 1 1 2 2 3 3
6
1 4 7 0
2 1
2 4
2 7
1 4 7 1
1 4 7 3
輸出
復制
5 0
5 2
5 1
具體解釋看代碼:
#include<bits/stdc++.h>
#define ll long long
using namespace std
;const int maxx
=2e5+100;
struct node
{int l
;int r
;int num
;
}p
[maxx
*40];
struct edge
{int to
,next
;
}e
[maxx
<<1];
struct ddd
{int x
,y
,t
;
}q
[maxx
];
int head
[maxx
<<1],dp
[maxx
][26];
int root
[maxx
],deep
[maxx
],val
[maxx
];
int n
,m
,tot
,rt
,ror
;
inline void init()
{memset(dp
,0,sizeof(dp
));memset(val
,0,sizeof(val
));memset(head
,-1,sizeof(head
));tot
=ror
=0;
}
inline void add(int u
,int v
)
{e
[tot
].to
=v
,e
[tot
].next
=head
[u
],head
[u
]=tot
++;
}
inline int build(int l
,int r
)
{int cur
=++ror
;p
[cur
].num
=0;if(l
==r
) return cur
;int mid
=l
+r
>>1;p
[cur
].l
=build(l
,mid
);p
[cur
].r
=build(mid
+1,r
);return cur
;
}
inline int update(int rot
,int l
,int r
,int pos
)
{int cur
=++ror
;p
[cur
]=p
[rot
];p
[cur
].num
++;if(l
==r
) return cur
;int mid
=l
+r
>>1;if(pos
<=mid
) p
[cur
].l
=update(p
[rot
].l
,l
,mid
,pos
);else p
[cur
].r
=update(p
[rot
].r
,mid
+1,r
,pos
);return cur
;
}
inline int query(int lrot
,int rrot
,int frot
,int ffrot
,int l
,int r
,int pos
)
{if(l
>pos
) return 0;if(r
<=pos
) return p
[lrot
].num
+p
[rrot
].num
-p
[frot
].num
-p
[ffrot
].num
;int mid
=l
+r
>>1;int ret
=0;if(pos
>=l
) ret
+=query(p
[lrot
].l
,p
[rrot
].l
,p
[frot
].l
,p
[ffrot
].l
,l
,mid
,pos
);if(pos
>mid
) ret
+=query(p
[lrot
].r
,p
[rrot
].r
,p
[frot
].r
,p
[ffrot
].r
,mid
+1,r
,pos
);return ret
;
}
inline void dfs(int u
,int f
)
{deep
[u
]=deep
[f
]+1;dp
[u
][0]=f
;for(int i
=1;i
<=25;i
++){if(dp
[u
][i
-1]) dp
[u
][i
]=dp
[dp
[u
][i
-1]][i
-1];else break;}root
[u
]=update(root
[f
],1,m
,val
[u
]);for(int i
=head
[u
];i
!=-1;i
=e
[i
].next
){int to
=e
[i
].to
;if(to
==f
) continue;dfs(to
,u
);}
}
inline int get_lca(int x
,int y
)
{if(deep
[x
]<deep
[y
]) swap(x
,y
);int tmp
=deep
[x
]-deep
[y
];for(int i
=0;i
<=25;i
++){if(tmp
&(1<<i
)) x
=dp
[x
][i
];}if(x
==y
) return x
;for(int i
=25;i
>=0;i
--){if(dp
[x
][i
]!=dp
[y
][i
]){x
=dp
[x
][i
];y
=dp
[y
][i
];}}return dp
[x
][0];
}
int main()
{init();int x
,op
,y
,c
;scanf("%d",&n
);for(int i
=1;i
<=n
;i
++) {scanf("%d",&x
);if(x
==0) rt
=i
;add(x
,i
);add(i
,x
);}scanf("%d",&m
);for(int i
=1;i
<=n
;i
++) val
[i
]=m
;int cnt
=0;for(int i
=1;i
<=m
;i
++){scanf("%d",&op
);if(op
==1){scanf("%d%d%d",&x
,&y
,&c
);q
[++cnt
].x
=x
,q
[cnt
].y
=y
,q
[cnt
].t
=i
-c
-1;}else {scanf("%d",&x
);val
[x
]=i
;}}root
[0]=build(1,m
);deep
[0]=0;dfs(rt
,0);for(int i
=1;i
<=cnt
;i
++){x
=q
[i
].x
,y
=q
[i
].y
,c
=q
[i
].t
;int Lca
=get_lca(x
,y
);printf("%d ",deep
[x
]+deep
[y
]-2*deep
[Lca
]+1);printf("%d\n",query(root
[x
],root
[y
],root
[Lca
],root
[dp
[Lca
][0]],1,m
,c
));}return 0;
}
努力加油a啊,(o)/~
總結
以上是生活随笔為你收集整理的[SCOI2015]情报传递(主席树+lca)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。