• 【BZOJ1103】大都市 解题报告


    题目传送门
    打算5分钟写完题解

    题目大意

    有一棵n个点的有根树, 初始时每条边均为红色,有两种操作:

    1. 把某条边染为蓝色
    2. 统计根到某一点路径上的红边数量

    思路

    1. (a_i)表示根到点i路径上的红边数,修改边(u,v)时,不失一般性,设(dep(u) < dep(v)),那么以v为根的子树中,所有(a_i)都要减1。用线段树点查区改
    2. 用黑科技欧拉序,不失一般性,设(dep(u) < dep(v)),把边(u,v)的颜色下放到点v,线段树/树状数组点改区查即可。

    关于欧拉序:算法导论中的DFS序好像就叫欧拉序,它有一个优越的性质:根到任意一点的路径对应欧拉序上的一段前缀区间

    易错点

    • 树状数组维护的范围是([1,2n]),而不是([1,n])
    • 无向边数组开2倍

    代码

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    const int maxn = 250007;
    int n, m, C[maxn << 1];
    int stamp, dep[maxn], tid[maxn], tif[maxn];
    bool vis[maxn];
    int edgenum, head[maxn], Next[maxn << 1], vet[maxn << 1];
    
    inline void addedge(int u, int v){
    	++edgenum;
    	vet[edgenum] = v;
    	Next[edgenum] = head[u];
    	head[u] = edgenum;
    }
    
    void DFS(int u, int D){
    	//printf("%d
    ", u);
    	vis[u] = true; tid[u] = ++stamp; dep[u] = D;
    	for (int e = head[u]; e; e = Next[e]){
    		int v = vet[e];
    		if (!vis[v]) DFS(v, D+1);
    	}
    	tif[u] = ++stamp;
    }
    
    inline void add(int i, int val){
    	for (; i <= n+n; i += (i & (-i)))
    		C[i] += val;
    }
    
    inline int sum(int i){
    	int res = 0;
    	for (; i >= 1; i -= (i & (-i)))
    		res += C[i];
    	return res;
    }
    
    int main(){
    	scanf("%d", &n);
    	for (int i = 1; i < n; ++i){
    		int u, v;
    		scanf("%d%d", &u, &v);
    		addedge(u,v);
    		addedge(v,u);
    	}
    	DFS(1, 1); 
    	for (int i = 2; i <= n; ++i){
    		add(tid[i], +1);
    		add(tif[i], -1); 
    	}
    	scanf("%d", &m);
    	for (int i = 1; i <= n + m - 1; ++i){
    		char T[2];
    		scanf("%s", T);
    		if (T[0] == 'A'){
    			int u,v;
    			scanf("%d%d", &u, &v);
    			if (dep[u] > dep[v]) swap(u, v);
    			add(tid[v], -1); add(tif[v], +1);
    		}else{
    			int a;
    			scanf("%d", &a);
    			printf("%d
    ", sum(tid[a]));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    AOJ 2200 Mr. Rito Post Office
    poj 3259 Wormholes
    01背包求解组合最值问题
    01背包求解面值组成问题
    金明的预算方案
    追赶法
    有关动态规划的一些定理。。。。。
    4980
    并查集
    快速幂
  • 原文地址:https://www.cnblogs.com/YJZoier/p/9432758.html
Copyright © 2020-2023  润新知