zoukankan      html  css  js  c++  java
  • [洛谷P3224][HNOI2012]永无乡

    题目大意:给你$n$个点,每个点有权值$k$,现有两种操作:

    1. $B;x;y:$将$x,y$所在联通块合并
    2. $Q;x;k:$查询第$x$个点所在联通块权值第$k$小是哪个数

    题解:线段树合并,权值线段树上二分即可

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cctype>
    namespace __IO {
    	namespace R {
    		int x, ch;
    		inline int read() {
    			ch = getchar();
    			while (isspace(ch)) ch = getchar();
    			for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
    			return x;
    		}
    		inline char readc() {
    			ch = getchar();
    			while (!isalpha(ch)) ch = getchar();
    			return ch;
    		}
    	}
    }
    using __IO::R::read;
    using __IO::R::readc;
    
    #define maxn 100010
    #define N (maxn * 50)
    
    int n, m;
    int w[maxn], ret[maxn];
    int rt[maxn], lc[N], rc[N], sz[N], idx;
    
    int f[maxn];
    int find(int x) {return x == f[x] ? x : (f[x] = find(f[x]));}
    
    void insert(int &rt, int l, int r, int num) {
    	if (!rt) rt = ++idx;
    	sz[rt]++;
    	if (l == r) return ;
    	int mid = l + r >> 1;
    	if (num <= mid) insert(lc[rt], l, mid, num);
    	else insert(rc[rt], mid + 1, r, num);
    }
    
    int __merge(int x, int y) {
    	if (!x || !y) return x | y;
    	sz[x] += sz[y];
    	lc[x] = __merge(lc[x], lc[y]);
    	rc[x] = __merge(rc[x], rc[y]);
    	return x;
    }
    void merge(int a, int b) {
    	int x = find(a), y = find(b);
    	if (x == y) return ;
    	rt[x] = __merge(rt[x], rt[y]);
    	f[y] = x;
    }
    int __query(int rt, int l, int r, int k) {
    	if (sz[rt] < k) return -1;
    	if (l == r) return l;
    	int mid = l + r >> 1;
    	if (sz[lc[rt]] >= k) return __query(lc[rt], l, mid, k);
    	else return __query(rc[rt], mid + 1, r, k - sz[lc[rt]]);
    }
    int query(int x, int k) {
    	x = find(x);
    	int res = __query(rt[x], 1, n, k);
    	return ~res ? ret[res] : -1;
    }
    
    int main() {
    	n = read(), m = read();
    	for (int i = 1; i <= n; i++) {
    		w[i] = read(), ret[w[i]] = f[i] = i;
    		insert(rt[i], 1, n, w[i]);
    	}
    	for (int i = 0, a, b; i < m; i++) {
    		a = read(), b = read();
    		merge(a, b);
    	}
    	int q = read();
    	while (q --> 0) {
    		char op = readc();
    		int x = read(), y = read();
    		if (op == 'B') merge(x, y);
    		else printf("%d
    ", query(x, y));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Python自动化运维之28、Django(二)
    Python自动化运维之27、Django(一)
    Python自动化运维之26、Web框架本质、MVC与MTV
    Python自动化运维之25、Ajax
    高级接口--高级群发接口
    高级接口--用户标签管理
    高级接口--获取用户基本信息
    高级接口--获取用户地理位置
    高级接口--生成带参数二维码
    高级接口--OAuth2.0网页授权
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10018539.html
Copyright © 2011-2022 走看看