Test instructions: There is a T set of test data, n for each set of data for N cities, the next n rows each row gives the coordinates of each city (0<=x,y<=1000000), and then there are M (1<m<200000) operations, there are two types of operations, (1) "Road A B" , which means that city A and city B are connected through a road, and if A and B are originally of different urban agglomerations, A and B are in a city group, and the road does not intersect other roads (except endpoints A and B). (2) "Line C", which indicates how many cities there are in the city, and the number of urban agglomerations when crossing y=c lines.
Train of thought: Segment tree Add and search set
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <iostream > #include <algorithm> #include <vector> #include <map> #include <queue> #include <stack& Gt #include <string> #include <map> #include <set> #define EPS 1e-6 #define LL Long long using namespace std; const int MAXN = 100000 + 100;const int maxl = 1000000 + 10;const int INF = 0x3f3f3f3f;int PA[MAXN], LOW[MAXN], HIGH[MAXN ], POS[MAXN], Node[maxn];int SUMV1[2*MAXL], ADDV1[2*MAXL]; How many states int SUMV2[2*MAXL], ADDV2[2*MAXL]; int N, M;//pa Save the Father node, low,high the upper and lower bounds of the connected component, node saves the number of nodes in the connected component int find (int x) {if (x! = Pa[x]) return pa[x] = find (pa[x]); retur n x;} void maintain1 (int o, int L, int R) {int LC = O*2, rc = O*2+1;sumv1[o] = 0;if (R > L) {//considering 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;//The add value of the cumulative boundary} else {int M = L + (r-l)/2;if (yl <= M) update1 (LC, L, M, V, yl, yr); if (y R > M) update1 (RC, m+1, R, V, yl, yr);} Maintain1 (o, L, R);//Recalculate additional information for this node before recursion ends} 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) {//considering 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 for cumulative boundary} else {int M = L + (r-l)/2;if (yl <= M) u PDATE2 (LC, L, M, V, yl, yr), if (Yr > M) update2 (RC, m+1, R, V, yl, yr);} Maintain2 (o, L, R);//recalculation before recursion endsAdditional information for this node} 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 (ADDV1)), 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 (fi nd (a)! = Find (b)) {if (High[pa[a]! = Low[pa[a]]) {update1 (1, 1, 1000000,-1, Low[pa[a]]+1, High[pa[a]]); Update2 (1, 1, 1000 -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]]);p a[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;}
Uvalive 4730 Kingdom Kingdom (and check set + line tree)