「UVA 1455」王国「互いに素セットメンテナンス間隔」、「フェンウィックの木」

まず、あなたは無用xは軸を観察する必要があり、これは計算幾何学で観察していません


その後、あなたは、のみについての彼のMINYとMAXYとの状態を観察する必要があり、この範囲内に持っていた行がある限り、確かに状態を通過しますので、

だから私たちは、それぞれの状態を置くことができる範囲に抽象化

2互いに素セット、更新されたルックMAXY、MINY、およびSZで、Bのマージを置くための修正動作のために、フェンウィックツリー上の間隔を変更することが

ライン上で直接質問を、あなたは、詳細を理解するために、コードを見ることができます

#include <bits/stdc++.h>

#define test(...) fprintf(stderr, __VA_ARGS__)
#define dbg(x) cerr << #x << " = " << x << '\n'

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\n", 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;
}

おすすめ

転載: www.cnblogs.com/LiM-817/p/12340472.html