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
    ");
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    复习:C#3.0面向对象测试开发包
    SQL Server 2000实现一则按类似VB VAL函数功能排序的案例
    SQL Server TEXT类型字段字符串替换示例处理脚本
    获取SQL Server服务器的连接信息用脚本(在原邹建写的基础上作一点改进)与一段查询SQL Server服务器阻塞和死锁信息用的脚本
    字符串前部去除自定义函数(TSQL)
    从数据库系统管理的角度上回答数据库是什么
    话说物联网
    赖床狂想记录
    M1非接触式射频存储卡卡唯一号(十六进制值表示),去除其前部为0的自定义函数
    SQLHelper类
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11334372.html
Copyright © 2011-2022 走看看