zoukankan      html  css  js  c++  java
  • [洛谷P3950]部落冲突

    题目大意:给你一棵树,有$3$个操作:

    1. $Q;p;q:$询问$p,q$是否连通
    2. $C;p;q:$把$p->q$这条边割断
    3. $U;x:$恢复第$x$次操作二

    题解:可以在割断时把这条边赋值上$1$,恢复时赋成$0$,只需要求$p->q$路径和是否为$0$即可,可以用$dfs$序+树状数组维护

    卡点:$LCA$越界

    C++ Code:

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    namespace __IO {
    	namespace R {
    		int x, ch;
    		inline int read() {
    			ch = getchar();
    			while (isspace(ch)) ch = getchar();
    			for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
    			return x;
    		}
    	}
    }
    using __IO::R::read;
    
    #define maxn 300010
    
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt;
    } e[maxn << 1];
    inline void add(int a, int b) {
    	e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    }
    
    int n, m;
    #define M 20
    int fa[maxn][M], sz[maxn], dep[maxn], dfn[maxn], idx;
    void dfs(int u) {
    	dfn[u] = ++idx;
    	sz[u] = 1;
    	for (int i = 1; i < M; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
    	for (int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (v != *fa[u]) {
    			*fa[v] = u;
    			dep[v] = dep[u] + 1;
    			dfs(v);
    			sz[u] += sz[v];
    		}
    	}
    }
    
    inline int LCA(int x, int y) {
    	if (x == y) return x;
    	if (dep[x] < dep[y]) std::swap(x, y);
    	for (int i = dep[x] - dep[y]; i; i &= i - 1) x = fa[x][__builtin_ctz(i)];
    	if (x == y) return x;
    	for (int i = M - 1; ~i; i--) if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
    	return *fa[x];
    }
    
    namespace BIT {
    	int Tr[maxn], res;
    	inline void modify(int p, int num) {for (; p <= n; p += p & -p) Tr[p] += num;}
    	inline int query(int p) {for (res = 0; p; p &= p - 1) res += Tr[p]; return res;}
    }
    
    inline void modify(int x, int num) {
    	BIT::modify(dfn[x], num);
    	BIT::modify(dfn[x] + sz[x], -num);
    }
    inline void query(int x, int y) {
    	int res = BIT::query(dfn[x]) + BIT::query(dfn[y]) - BIT::query(dfn[LCA(x, y)]) * 2;
    	puts(res ? "No" : "Yes");
    }
    
    int war[maxn], Tim;
    int main() {
    	n = read(), m = read();
    	for (int i = 1, a, b; i < n; i++) {
    		a = read(), b = read();
    		add(a, b);
    		add(b, a);
    	}
    	dfs(1);
    	while (m --> 0) {
    		int x, y;
    		char op = getchar();
    		while (!isalpha(op)) op = getchar();
    		switch (op) {
    			case 'Q':
    				x = read(), y = read();
    				query(x, y);
    				break;
    			case 'C':
    				x = read(), y = read();
    				if (dep[x] < dep[y]) std::swap(x, y);
    				war[++Tim] = x;
    				modify(x, 1);
    				break;
    			case 'U':
    				x = read();
    				modify(war[x], -1);
    				break;
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    从零开始入门 K8s | 应用编排与管理
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    203. Remove Linked List Elements
    183. Customers Who Never Order
    182. Duplicate Emails
    181. Employees Earning More Than Their Managers
    1261. Find Elements in a Contaminated Binary Tree
    1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9997465.html
Copyright © 2011-2022 走看看