zoukankan      html  css  js  c++  java
  • dfs+线段树 zhrt的数据结构课

    zhrt的数据结构课

    这个题目我觉得是一个有一点点思维的dfs+线段树

    虽然说看起来可以用树链剖分写,但是这个题目时间卡了树剖

    因为之前用树剖一直在写这个,所以一直想的是区间更新,想dfs+线段树,有点点没想明白

    后来才知道可以把这个区间更新转化成单点更新,就是查一个结点的子树,如果子树有可以到根节点的,那么这个结点肯定也可以到根节点。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <vector>
    #include <stack>
    #include <map>
    #include <string>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn = 4e5 + 10;
    int sum[maxn * 4];
    
    void push_up(int id)
    {
    	sum[id] = sum[id << 1 | 1] + sum[id << 1];
    }
    
    void build(int id,int l,int r)
    {
    	if(l==r)
    	{
    		sum[id] = 0;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(id << 1, l, mid);
    	build(id << 1 | 1, mid + 1, r);
    	push_up(id);
    }
    
    void update(int id,int l,int r,int pos,int val)
    {
    	if(l==r)
    	{
    		sum[id] += val;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	if (pos <= mid) update(id << 1, l, mid, pos, val);
    	else update(id << 1 | 1, mid + 1, r, pos, val);
    	push_up(id);
    }
    
    int query(int id,int l,int r,int x,int y)
    {
    	// printf("id=%d l=%d r=%d x=%d y=%d
    ", id, l, r, x, y);
    	if (x <= l && y >= r) return sum[id];
    	int mid = (l + r) >> 1;
    	int ans = 0;
    	if (x <= mid) ans += query(id << 1, l, mid, x, y);
    	if (y > mid) ans += query(id << 1 | 1, mid + 1, r, x, y);
    	return ans;
    }
    int el[maxn], er[maxn], tot = 0, head[maxn], cnt;
    struct node
    {
    	int v, nxt;
    	node(int v=0,int nxt=0):v(v),nxt(nxt){}
    }ex[maxn];
    
    void init()
    {
    	memset(head, -1, sizeof(head));
    	tot = 0, cnt = 0;
    }
    
    void add(int u,int v)
    {
    	ex[cnt] = node(v, head[u]);
    	head[u] = cnt++;
    	ex[cnt] = node(u, head[v]);
    	head[v] = cnt++;
    	// printf("u=%d v=%d
    ", u, v);
    }
    
    void dfs(int u,int pre)
    {
    	el[u] = ++tot;
    	for(int i=head[u];i!=-1;i=ex[i].nxt)
    	{
    		int v = ex[i].v;
    		if (v == pre) continue;
    		dfs(v, u);
    	}
    	er[u] = tot;
    	// printf("el[%d]=%d er[%d]=%d
    ", u, el[u], u, er[u]);
    }
    
    int main()
    {
    	int t;
    	scanf("%d", &t);
    	while(t--)
    	{
    		init();
    		int n, m;
    		scanf("%d%d", &n, &m);
    		build(1, 1, n);
    		for(int i=1;i<n;i++)
    		{
    			int u, v;
    			scanf("%d%d", &u, &v);
    			add(u, v);
    		}
    		dfs(1, -1);
    		while(m--)
    		{
    			int opt, x;
    			scanf("%d%d", &opt, &x);
    			if (opt == 0) update(1, 1, n, el[x], 1);
    			if (opt == 1) update(1, 1, n, el[x], -1);
    			if (opt == 2)
    			{
    				int ans = query(1, 1, n, el[x], er[x]);
    				if (ans) printf("Yes
    ");
    				else printf("No
    ");
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    BFS visit tree
    Kth Largest Element in an Array 解答
    Merge k Sorted Lists 解答
    Median of Two Sorted Arrays 解答
    Maximal Square 解答
    Best Time to Buy and Sell Stock III 解答
    Best Time to Buy and Sell Stock II 解答
    Best Time to Buy and Sell Stock 解答
    Triangle 解答
    Unique Binary Search Trees II 解答
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11334372.html
Copyright © 2011-2022 走看看