zoukankan      html  css  js  c++  java
  • Bzoj3551: [ONTAK2010]Peaks加强版

    题面

    题目传送门

    (Bytemountains)(N)座山峰,每座山峰有他的高度(h_i)
    有些山峰之间有双向道路相连,共(M)条路径,每条路径有一个困难值,这个值越大表示越难走
    现在有(Q)组询问
    每组询问询问从点(v)开始只经过困难值小于等于(x)的路径所能到达的山峰中第(k)高的山峰,如果无解输出(-1)
    (N<=10^5, M,Q<=5*10^5)(h_i,c,x<=10^9)

    Sol

    (Kruskal)重构树+倍增+主席树
    做一遍(Kruskal)最小生成树
    询问时(v)往上跳到最后一个小于等于(x)的值,然后求这个点的子树的叶节点的第(k)大,可以证明这个子树外的无论如何都走不到

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(2e5 + 5);
    const int __(5e5 + 5);
    
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, m, q, L[_], R[_], w[_], h[_], fa[_], anc[20][_], id[_];
    int o[_], len;
    struct Link{
    	int u, v, w;
    
    	IL bool operator <(RG Link B) const{
    		return w < B.w;
    	}
    } lnk[__];
    int first[_], cnt, num, idx;
    struct Edge{
    	int to, next;
    } edge[_];
    
    IL void Add(RG int u, RG int v){
    	edge[cnt] = (Edge){v, first[u]}, first[u] = cnt++;
    }
    
    IL int Find(RG int x){
    	return x == fa[x] ? x : fa[x] = Find(fa[x]);
    }
    
    IL void Dfs(RG int u){
    	L[u] = n, R[u] = 1;
    	if(u <= n) L[u] = R[u] = ++idx, id[idx] = u;
    	for(RG int e = first[u]; e != -1; e = edge[e].next){
    		RG int v = edge[e].to;
    		anc[0][v] = u, Dfs(v);
    		L[u] = min(L[u], L[v]), R[u] = max(R[u], R[v]);
    	}
    }
    
    int rt[_], tot;
    struct HJT{
    	int ls, rs, sz;
    } T[_ * 20];
    
    IL void Modify(RG int &x, RG int l, RG int r, RG int p){
    	T[++tot] = T[x], T[x = tot].sz++;
    	if(l == r) return;
    	RG int mid = (l + r) >> 1;
    	if(p <= mid) Modify(T[x].ls, l, mid, p);
    	else Modify(T[x].rs, mid + 1, r, p);
    }
    
    IL int Query(RG int A, RG int B, RG int l, RG int r, RG int k){
    	if(l == r) return o[l];
    	RG int mid = (l + r) >> 1, size = T[T[B].rs].sz - T[T[A].rs].sz;
    	if(k <= size) return Query(T[A].rs, T[B].rs, mid + 1, r, k);
    	return Query(T[A].ls, T[B].ls, l, mid, k - size);
    }
    
    IL int Calc(RG int u, RG int x, RG int k){
    	RG int p = u;
    	for(RG int j = 18; ~j; --j) if(anc[j][p] && w[anc[j][p]] <= x) p = anc[j][p];
    	if(R[p] - L[p] + 1 < k) return -1;
    	return Query(rt[L[p] - 1], rt[R[p]], 1, len, k);
    }
    
    int main(RG int argc, RG char* argv[]){
    	num = n = Input(), m = Input(), q = Input();
    	for(RG int i = 1; i <= n; ++i) fa[i] = i, o[i] = h[i] = Input();
    	sort(o + 1, o + n + 1), len = unique(o + 1, o + n + 1) - o - 1;
    	for(RG int i = 1; i <= n; ++i) h[i] = lower_bound(o + 1, o + len + 1, h[i]) - o;
    	for(RG int i = 1; i <= m; ++i) lnk[i].u = Input(), lnk[i].v = Input(), lnk[i].w = Input();
    	sort(lnk + 1, lnk + m + 1), Fill(first, -1);
    	for(RG int i = 1; i <= m; ++i){
    		RG int fx = Find(lnk[i].u), fy = Find(lnk[i].v);
    		if(fx == fy) continue;
    		w[++num] = lnk[i].w, fa[fx] = fa[fy] = fa[num] = num;
    		Add(num, fx), Add(num, fy);
    	}
    	for(RG int i = 1; i <= num; ++i) if(fa[i] == i) Dfs(i);
    	for(RG int j = 1; j <= 18; ++j)
    		for(RG int i = 1; i <= num; ++i)
    			anc[j][i] = anc[j - 1][anc[j - 1][i]];
    	for(RG int i = 1; i <= n; ++i) rt[i] = rt[i - 1], Modify(rt[i], 1, len, h[id[i]]);
    	for(RG int i = 1, ans = 0; i <= q; ++i){
    		RG int v = Input(), x = Input(), k = Input();
    		if(ans != -1) v ^= ans, x ^= ans, k ^= ans;
    		printf("%d
    ", ans = Calc(v, x, k));
    	}
        return 0;
    }
    
    
  • 相关阅读:
    Java 快速入门-06-JDK 目录文件说明
    Java快速入门-05-数组循环条件 实例《延禧攻略》
    腾讯云服务器 选购+远程控制 图文教程
    无法获得锁 /var/lib/dpkg/lock
    Ubuntu 安装 PhpMyAdmin 图文教程
    基于Redis的BloomFilter算法去重
    CAP理论
    Linux常用命令回顾
    基于Solr实现HBase的二级索引
    Solr搜索服务架构图
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8559590.html
Copyright © 2011-2022 走看看