zoukankan      html  css  js  c++  java
  • 「题解」洛谷P5311 [Ynoi2011] 成都七中

    对于每一个询问,在点分树上一定存在一个最浅的点,满足这个点是 (x) 在点分树中的祖先,且在点分树上到 (x) 经过的点编号最小/大值组成的区间 ([min,max])([l,r]) 包含,那么所有编号在 ([l,r]) 内的与 (x) 连通的点,一定都在点分树中这个最浅的点的子树内,因为如果存在另一个点不在这个子树内且与 (x) 连通,则这个不在子树内的点和我们找到的最浅的点之间一定存在一个路径,经过的编号都是合法的。所以他们的 LCA 也是合法的,既然 LCA 合法并且更浅,与我们“找到的最浅的点”相矛盾。

    所以把每个询问离线下来,找到对应的最浅的点,让这个最浅的点处理这个询问。问题转化成了求一个(点分树中的)有根树中与 (x) 在原树中连通的连通块颜色数。

    发现一个点满足条件当且仅当这个点到根经过的点的 (mingeq l,max leq r),也就是经过的每一个点都满足条件。

    对于每一个分治中心处理这个询问,是一个二维数颜色问题,和二维数点问题差不多一样做就行,按照 (l) 从后往前扫,记录每个颜色之前出现的最小的 (r),对于每个颜色只在最小的 (r)(+1) 即可。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T>
    T& read(T& r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    const int N = 100010;
    inline int lowbit(int x) { return x & (-x); }
    int n, m, head[N], ent, tot;
    int tree[N];
    void modify(int x, int v) { for(; x <= n; x += lowbit(x)) tree[x] += v; }
    int query(int x) { int sumq = 0; for(; x; x -= lowbit(x)) sumq += tree[x]; return sumq; }
    int mx[N], siz[N], fa[N], col[N], col_[N], lst[N], ans[N];
    int all, rt, now;
    bool vis[N];
    struct Edge {
    	int next, to;
    }e[N << 1];
    inline void add(int x, int y) {
    	e[++ent].to = y; e[ent].next = head[x]; head[x] = ent;
    }
    struct Node {
    	int l, r, id;
    	Node(int ll = 0, int rr = 0, int idd = 0) { l = ll; r = rr; id = idd; }
    };
    bool cmp(Node x, Node y) { return x.l == y.l ? x.id > y.id : x.l > y.l; }
    std::vector<Node>vec1[N], vec2[N];
    void dfs(int x, int f, int mn, int mx) {
    	vec1[x].push_back(Node(mn, mx, rt)); vec2[rt].push_back(Node(mn, mx, col[x]));
    	siz[x] = 1;
    	for(int i = head[x]; i; i = e[i].next) {
    		int v = e[i].to; if(v == f || vis[v]) continue ;
    		dfs(v, x, Min(mn, v), Max(mx, v));
    		siz[x] += siz[v];
    	}
    }
    void getrt(int x, int f) {
    	mx[x] = siz[x] = 1;
    	for(int i = head[x]; i; i = e[i].next) {
    		int v = e[i].to; if(v == f || vis[v]) continue ;
    		getrt(v, x); siz[x] += siz[v]; mx[x] = Max(mx[x], siz[v]);
    	} mx[x] = Max(mx[x], all - siz[x]);
    	if(!rt || mx[x] < now) rt = x, now = mx[x];
    }
    void work(int x) {
    	all = siz[x]; rt = 0; now = 0x7fffffff;
    	getrt(x, 0); vis[rt] = 1;
    	dfs(x = rt, 0, rt, rt);
    	for(int i = head[x]; i; i = e[i].next) {
    		int v = e[i].to; if(vis[v]) continue ;
    		work(v);
    	}
    }
    signed main() { //freopen("in.txt", "r", stdin);
    	read(n); read(m); 
    	for(int i = 1; i <= n; ++i) col_[i] = read(col[i]);
    	std::sort(col_+1, col_+n+1);
    	tot = std::unique(col_+1, col_+n+1) - col_ - 1;
    	for(int i = 1; i <= n; ++i) col[i] = std::lower_bound(col_+1, col_+tot+1, col[i]) - col_;
    	for(int i = 1, u, v; i < n; ++i) read(u), read(v), add(u, v), add(v, u);
    	siz[1] = n;
    	work(1);
    	for(int i = 1; i <= m; ++i) {
    		int x, y, z; read(x); read(y); read(z);
    		for(auto j : vec1[z]) {
    			if(j.l >= x && j.r <= y) {
    				vec2[j.id].push_back(Node(x, y, -i));
    				break ;
    			}
    		}
    	}
    	for(int i = 1; i <= n; ++i) {
    		std::sort(vec2[i].begin(), vec2[i].end(), cmp);
    		for(auto j : vec2[i]) {
    			if(j.id < 0)
    				ans[-j.id] = query(j.r);
    			else {
    				if(!lst[j.id] || lst[j.id] > j.r) {
    					if(lst[j.id]) modify(lst[j.id], -1);
    					lst[j.id] = j.r;
    					modify(lst[j.id], 1);
    				}
    			}
    		}
    		for(auto j : vec2[i])
    			if(j.id > 0 && lst[j.id]) {
    				modify(lst[j.id], -1);
    				lst[j.id] = 0;
    			}
    	}
    	for(int i = 1; i <= m; ++i) printf("%d
    ", ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    网站无脑搭建,自己可以建个站玩一玩儿
    Python2和Python3中urllib库中urlencode的使用注意事项
    图像的缩放与图像金字塔
    模糊聚类算法(FCM)
    java调用python脚本
    雷林鹏分享:jsp HTTP 状态码
    雷林鹏分享:jsp 服务器响应
    雷林鹏分享:jsp 客户端请求
    雷林鹏分享:jsp 隐式对象
    雷林鹏分享:jsp 动作元素
  • 原文地址:https://www.cnblogs.com/do-while-true/p/15146269.html
Copyright © 2011-2022 走看看