zoukankan      html  css  js  c++  java
  • 「UVA 1455」Kingdom 「并查集维护区间」「Fenwick Tree」

    首先你得观察到x轴没用,不观察这个就是个计算几何


    然后你得观察到一个州只跟他的maxy和miny有关,因为只要有一条线在这个范围内过肯定会经过这个州

    所以就可以把每个州抽象成一个区间

    对于修改操作就把a,b两个并查集merge一下,更新一下maxy,miny和sz,在树状数组上进行区间修改

    询问直接询问就行了,细节可以看代码理解

    #include <bits/stdc++.h>
    
    #define test(...) fprintf(stderr, __VA_ARGS__)
    #define dbg(x) cerr << #x << " = " << x << '
    '
    
    using namespace std;
    
    typedef long long ll;
    typedef pair <int, int> pii;
    typedef vector <int> vi;
    typedef unsigned int ui;
    typedef vector <pair <int, int> > edges;
    
    const int Limit = 2000010, N = 100010;
    int n, m;
    int miny[N], maxy[N], sz[N], par[N];
    int find_par(int x) {
    	return x == par[x] ? par[x] : par[x] = find_par(par[x]);
    }
    struct BIT {
    int c[Limit], mmax;
    void position_add(int x, int v) {
    	for (; x <= mmax; x += (x & -x)) c[x] += v; 
    }
    void add(int l, int r, int v) {
    	position_add(l, v);
    	position_add(r, -v);
    }
    int qry(int x) {
    	int ans = 0; 
    	for (; x; x -= (x & -x)) ans += c[x];
    	return ans; 
    }
    }states, city;
    void solve() {
    	scanf ("%d", &n);
    	int mmax = 0;
    	for (int i = 1; i <= n; ++i) {
    		int x, y;
    		scanf ("%d%d", &x, &y);
    		y++;
    		y *= 2; 
    		mmax = max(mmax, y);
    		miny[i] = y;
    		maxy[i] = y;
    		sz[i] = 1; 
    		par[i] = i;
    	} 
    	states.mmax = city.mmax = mmax;
    	scanf ("%d", &m);
    	while (m--) {
    		char s[5];
    		int A, B, C;
    		scanf ("%s", s);
    		if (s[0] == 'r') {
    			scanf ("%d%d", &A, &B);
    			++A, ++B;
    			int xx = find_par(A), yy = find_par(B);
    			if (xx != yy) {
    				int L1 = miny[xx], R1 = maxy[xx];
    				int L2 = miny[yy], R2 = maxy[yy];
    				states.add(L1, R1, -1);
    				states.add(L2, R2, -1);
    				states.add(min(L1, L2), max(R1, R2), 1);
    				city.add(L1, R1, -sz[xx]);
    				city.add(L2, R2, -sz[yy]);
    				city.add(min(L1, L2), max(R1, R2), sz[xx] + sz[yy]);
    				par[xx] = yy;
    				sz[yy] += sz[xx];
    				maxy[yy] = max(maxy[yy], maxy[xx]);
    				miny[yy] = min(miny[yy], miny[xx]);
    			//	dbg("Here");
    			}
    		} else if (s[0] == 'l') {
    			int extra;
    			scanf ("%d.%d", &C, &extra);
    			C++;
    			C *= 2; C++;
    			printf("%d %d
    ", states.qry(C), city.qry(C));
    		}
    	}
    	for (int i = 1; i <= n; ++i) {
    		if (par[i] == i)
    			states.add(miny[i], maxy[i], -1), 
    			city.add(miny[i], maxy[i], -sz[i]);
    	}
    }
    
    int main() {
    #ifdef LOCAL
    	freopen("sample.in", "r", stdin);
    #endif
      int tests;
      scanf ("%d", &tests);
      while (tests--) solve();
      return 0;
    }
    
  • 相关阅读:
    第二十篇:不为客户连接创建子进程的并发回射服务器(poll实现)
    第十九篇:不为客户连接创建子进程的并发回射服务器(select实现)
    第十八篇:批量处理情况下的回射客户端
    第十七篇:IO复用之select实现
    修改文件中的内容,使用fileinput模块
    登陆脚本
    内置函数 字符串操作
    loj 1316(spfa预处理+状压dp)
    loj 1099(最短路)
    loj 1044(dp+记忆化搜索)
  • 原文地址:https://www.cnblogs.com/LiM-817/p/12340472.html
Copyright © 2011-2022 走看看