Uvalive 4730 kingdom (and query set + line segment tree)
Zookeeper
There are T groups of test data. N of each group of data indicates that there are N cities, and each row in the next N rows shows the coordinates of each city (0 <= x, y <= 1000000), then M (1
Train of Thought: Add and query a set of Line Segments
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define eps 1e-6 # define LL long using namespace std; const int maxn = 100000 + 100; const int maxl = 1000000 + 10; const int INF = 0x3f3f3f; int pa [maxn], low [maxn], high [maxn], pos [maxn], node [maxn]; int sumv1 [2 * maxl], addv1 [2 * maxl]; // number of States int sumv2 [2 * maxl], addv2 [2 * maxl]; int n, m; // pa stores the parent node, low, high stores the upper and lower boundaries of the connected component, and node stores the number of nodes in the connected component int find (int x) {if (x! = Pa [x]) return pa [x] = find (pa [x]); return x;} void maintain1 (int o, int L, int R) {int lc = o * 2, rc = o * 2 + 1; sumv1 [o] = 0; if (R> L) {// consider the left and right subtree sumv1 [o] = sumv1 [lc] + sumv1 [rc];} sumv1 [o] + = addv1 [o] * (R-L + 1 ); // consider the add operation} void update1 (int o, int L, int R, int v, int yl, int yr) {int lc = o * 2, rc = o * 2 + 1; if (yl <= L & yr> = R) {// recursive boundary addv1 [o] + = v; // add value for the accumulate boundary} else {int M = L + (R-L)/2; if (yl <= M) Update1 (lc, L, M, v, yl, yr); if (yr> M) update1 (rc, M + 1, R, v, yl, yr );} maintain1 (o, L, R); // re-calculate the additional information of the current node before the end of recursion} int query1 (int o, int L, int R, int add, int yl, int yr) {if (yl <= L & yr> = R) {return sumv1 [o] + add * (R-L + 1);} else {int ans = 0; int M = L + (R-L)/2; if (yl <= M) ans + = query1 (o * 2, L, M, add + addv1 [o], yl, yr); if (yr> M) ans + = query1 (o * 2 + 1, M + 1, R, add + addv1 [o], yl, yr); return ans ;}} Void maintain2 (int o, int L, int R) {int lc = o * 2, rc = o * 2 + 1; sumv2 [o] = 0; if (R> L) {// consider the left and right subtree sumv2 [o] = sumv2 [lc] + sumv2 [rc];} sumv2 [o] + = addv2 [o] * (R-L + 1); // consider the add operation} void update2 (int o, int L, int R, int v, int yl, int yr) {int lc = o * 2, rc = o * 2 + 1; if (yl <= L & yr> = R) {// recursive boundary addv2 [o] + = v; // add Value of the accumulative boundary} else {int M = L + (R-L)/2; if (yl <= M) update2 (lc, L, M, v, yl, yr); if (yr> M) up Date2 (rc, M + 1, R, v, yl, yr);} maintain2 (o, L, R ); // re-calculate the additional information of the current node before the end of recursion} int query2 (int o, int L, int R, int add, int yl, int yr) {if (yl <= L & yr> = R) {return sumv2 [o] + add * (R-L + 1);} else {int ans = 0; int M = L + (R-L)/2; if (yl <= M) ans + = query2 (o * 2, L, M, add + addv2 [o], yl, yr); if (yr> M) ans + = query2 (o * 2 + 1, M + 1, R, add + addv2 [o], yl, yr ); return ans ;}} void init () {memset (addv1, 0, sizeof (Ddv1); memset (addv2, 0, sizeof (addv2); memset (sumv1, 0, sizeof (sumv1); memset (sumv2, 0, sizeof (sumv2 )); cin> n; for (int I = 0; I <n; I ++) {int tmp; cin> tmp> pos [I];} for (int I = 0; I <n; I ++) {pa [I] = I; node [I] = 1; high [I] = low [I] = pos [I];} cin> m;} void solve () {char cmd [5]; int a, B; float c; while (m --) {cin> cmd; if (cmd [0] = 'R') {cin> a> B; if (find ()! = Find (B) {if (high [pa [a]! = Low [pa [a]) {update1 (1, 1, 1000000,-1, low [pa [a] + 1, high [pa [a]); update2 (1, 1, 1000000,-node [pa [a], low [pa [a] + 1, high [pa [a]);} if (high [pa [B]! = Low [pa [B]) {update1 (1, 1, 1000000,-1, low [pa [B] + 1, high [pa [B]); update2 (1, 1, 1000000,-node [pa [B], low [pa [B] + 1, high [pa [B]);} node [pa [a] + = node [pa [B]; low [pa [a] = min (low [pa [a], low [pa [B]); high [pa [a] = max (high [pa [a], high [pa [B]); pa [pa [B] = pa [a]; if (high [pa [a]! = Low [pa [a]) {update1 (1, 1, 1000000, 1, low [pa [a] + 1, high [pa [a]); update2 (1, 1, 1000000, node [pa [a], low [pa [a] + 1, high [pa [a]) ;}} else {cin> c; cout <query1 (1, 1, 1000000, 0, (int) (c + 1), (int) (c + 1 )) <"; cout <query2 (1, 1, 1000000, 0, (int) (c + 1), (int) (c + 1) <endl; // cout <(int) (c + 1) <endl ;}} int main () {// freopen ("input.txt", "r", stdin ); int t; cin> t; while (t --) {init (); solve ();} return 0 ;}