Codeforces Round #266 (Div. 2) Problem E Solution

来源:互联网 发布:陈奕迅苦瓜知乎 编辑:程序博客网 时间:2024/05/18 02:23

题目大意:

自己去看。。。


Solution:

直接离线进行处理,首先构建出完整的树,处理出dfs序。对于每个询问,事实上是问一个点是否在一条路径上,究竟是哪条路径可以利用并查集维护。

那么我们就需要知道一个点u是否是另一个点v的祖先。

事实上,这等价于:in[u]<=in[v]&&out[u]>=out[v].

于是总的时间复杂度为O(n\alpha(n)).


Code:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cctype>using namespace std;inline int getc() {static const int L = 1 << 15;static char buf[L], *S = buf, *T = buf;if (S == T) {T = (S = buf) + fread(buf, 1, L, stdin);if (S == T)return EOF;}return *S++;}inline int getint() {int c;while(!isdigit(c = getc()));int tmp = c - '0';while(isdigit(c = getc()))tmp = (tmp << 1) + (tmp << 3) + c - '0';return tmp;}#define N 100010int head[N], next[N], end[N];void addedge(int a, int b) {static int q = 1;end[q] = b;next[q] = head[a];head[a] = q++;}int root[N], size[N];int find(int x) {return x == root[x] ? x : root[x] = find(root[x]);}int down[N], up[N];struct Ask {int ins, lab;Ask(int _ins = 0, int _lab = 0):ins(_ins),lab(_lab){}}S[N];int num;int in[N], out[N], tclock;bool vis[N];void dfs(int x) {vis[x] = 1;in[x] = ++tclock;for(int j = head[x]; j; j = next[j])dfs(end[j]);out[x] = tclock;}inline bool inanc(int Son, int Anc) {return in[Anc] <= in[Son] && out[Anc] >= out[Son];}int main() {int n, m;n = getint();m = getint();register int i;for(i = 1; i <= n; ++i)root[i] = i, size[i] = 1;int sign, now = 0, a, b, x;for(i = 1; i <= m; ++i) {sign = getint();if (sign == 1) {a = getint(), b = getint();addedge(b, a);vis[a] = 1;root[a] = b;}if (sign == 2) {a = getint();down[++now] = a;up[now] = find(a);}if (sign == 3) {a = getint(), x = getint();S[++num] = Ask(a, x);}}for(i = 1; i <= n; ++i)if (!vis[i])dfs(i);for(i = 1; i <= num; ++i) {if (inanc(down[S[i].lab], S[i].ins) && inanc(S[i].ins, up[S[i].lab]))puts("YES");elseputs("NO");}return 0;}


0 0
原创粉丝点击