B Water
b words can be done in a fancy way
Line tree can
Priority queues can be
The best way to do this is to xi,yi a segment after discrete.
Divided into two endpoints XI and yi+1
Indicates that a line segment will be added at the Xi point, and a segment will be reduced in yi+1
Use an array to save the a[xi]++, a[yi+1]--, and then ask for the maximum prefix of a array.
Question C is a DP.
Test instructions Yes, there are N (1e3) number pairs, a[i],b[i]
A person has m (1e3) of energy, in order each time can be in a[i] or b[i] Select a number or a number is not selected, but select B[i] will spend 1 energy, ask him to choose the longest ascending sub-sequence of the length of what
Dp[i][j][l] means I in the longest ascending subsequence, has lost the J-Point Energy, the first person converts the number of the longest ascending subsequence of AI and Bi, can get the equation Dp[i][j][0]=max{dp[k][j][0] (a[k]<a[i]) +1,dp[ K][J][1] (B[k]<a[i]) +1},dp[i][j][1]=max (Dp[k][j-1][0] (A[k]<b[i]) +1,dp[k][j-1][1] (B[k]<b[i]) +1).
This looks like a n^3.
We can optimize into n^2 logn.
The practice is to use a tree-like array, similar to the sum of the method, you can also find the maximum value, then a total of m+1 tree-like array.
Open an array of dp[i][j] to the number of the first, the remaining J energy of the longest ascending subsequence.
The largest DP value in a number smaller than a[i] is found in the first J tree array, and the tree array can be updated at the same time
Then in the j+1 tree array to find the largest DP value in a number smaller than b[i], you can also update the J Tree array, because it consumes 1 of the energy
Read the bin God code, learned a bit
Question D,
Test instructions is very simple, there is a person, there is Q (5e4) operation,
Each operation has two, one is to insert a three-dimensional point, and the other is to ask how many three-dimensional points are in the range of X1,Y1,Z1 to x2,y2,z2 (i.e. x1<=x<=x2, Y1<=y<=y2, Z1<=Z<=Z2, The number of points (x, y, z) that meet the requirements
I was just beginning to use three-dimensional tree arrays. Using fancy hash, the result is tle.
The game thought of CDQ but did not think.
It's easy to understand after the game.
In particular, the first x1,y1,z1 to x2,y2,z2 this interval has how many three-dimensional points, converted to find some points to the origin of the number of points in this interval.
Then CDQ divide the rule, this can take time this one dimension to kill, after kill according to X sort, then use CDQ, then x this one dimension also kill, then the Y is sorted, then the remaining this one dimension z can use tree-like array to statistic.
This can also be extended to multi-dimensional interval to find the number of points.
Note that there is a fancy way to reduce complexity. For example, if we have an array a, if we use a only a fraction of a, it's a waste of time to assume that every time we memset initialize it.
Then open an array vis for the timestamp, vis[i] = 2 means we use this position at the 2nd point in time, so every time we count, we can count all the vis[i]=2 positions.
Each time a location is updated, the vis of that position is changed to the current timestamp.
Reference to the code of the Chnlich.
Problem C Code
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath > #include <algorithm> #include <map> #define MAXN 1111#define maxm 222222#define INF 1000000001using namespace std;struct BIT {int A[MAXN * 2]; int n; void init (int _n) {n = _n; for (int i = 1; I <= n; i++) a[i] = 0; } int lowbit (int x) {return x & x; } int getsum (int x) {int s = 0; for (int i = x; i > 0; I-= Lowbit (i)) {s = max (S, A[i]); } return s; } void Add (int x, int v) {for (int i = x; i <= n; i + = Lowbit (i)) {a[i] = max (a[i], V); }}}bit[maxn];int A[MAXN], B[MAXN], c[2 * maxn];int main () {int T, n, M, CNT; scanf ("%d", &t); while (t--) {cnt = 0; scanf ("%d%d", &n, &m); for (int i = 0; i < n; i++) {scanf ("%d%d", &a[i], &b[i]); c[cnt++] = A[i]; c[cnt++] = B[i]; } sort (c, C + CNT); CNT = unique (c, C + CNT)-C; for (int i = 0; i < n; i++) {A[i] = Lower_bound (c, C + CNT, a[i])-C + 1; B[i] = Lower_bound (c, C + CNT, b[i])-C + 1; } int ans = 0; for (int i = 0; I <= m; i++) Bit[i].init (CNT); for (int i = 0, i < n; i++) {for (int j = 0; J <= M; j + +) {int mx = bit[j].getsum (A[i]-1 ) + 1; Bit[j].add (A[i], MX); ans = max (ans, MX); if (J < m) {mx = bit[j + 1].getsum (B[i]-1) + 1; Bit[j].add (B[i], MX); ans = max (ans, MX); }}} printf ("%d\n", ans); } return 0;}Problem Code D
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath > #include <algorithm> #include <map> #define MAXN 55555#define maxm 222222#define INF 1000000001using Namespace Std;int NX, NY, NZ, N;int XA[MAXN], YA[MAXN], ZA[MAXN], XB[MAXN], YB[MAXN], ZB[MAXN], Op[maxn];int CX[MAXN * 2], CY[MAXN * 2], CZ[MAXN * 2];int LT[MAXN * 8], LX[MAXN * 8], ANS[MAXN * 8], CT1, CT2, m;struct q{int op, x, Y, Z; Q () {} q (int _op, int _x, int _y, int _z) {op = _op; x = _x; y = _y; z = _z;}} Q[MAXN * 8];bool cmpx (int x, int y) {if (q[x].x = = q[y].x) return Q[x].op < Q[y].op; return q[x].x < q[y].x;} BOOL Cmpy (int x, int y) {if (q[x].y = = q[y].y) return Q[x].op < Q[y].op; return q[x].y < Q[y].y;} struct BIT {int A[MAXN * 2], VIS[MAXN * 2], Ind; void CLR () {ind++; } int lowbit (int x) {return x & x; } int getsum (int x) {int s = 0; for (int i = x; i > 0; I-= lOwbit (i)) {if (vis[i] = = IND) s + = A[i]; } return s; } void Add (int x, int v) {for (int i = x; I <= nz; i + = Lowbit (i)) {if (vis[i] = = IND) A[i] + = V; else vis[i] = ind, a[i] = v; }}}bit;void Gao () {bit.clr (); Sort (lx + 1, lx + ct2 + 1, cmpy); for (int i = 1; I <= ct2; i++) {if (Q[lx[i]].op = = 1) bit.add (q[lx[i]].z, 1); else Ans[lx[i]] + = Bit.getsum (q[lx[i]].z); }}void CDQ2 (int l, int r) {if (L >= R) return; int mid = (L + r) >> 1; CT2 = 0; for (int i = l; I <= mid; i++) if (Q[lt[i]].op = = 1) lx[++ct2] = Lt[i]; for (int i = mid + 1; I <= R; i++) if (Q[lt[i]].op = = 2) Lx[++ct2] = Lt[i]; Gao (); CDQ2 (L, mid); CDQ2 (mid + 1, r);} void Cdq (int l, int r) {if (L >= R) return; int mid = (L + r) >> 1; CT1 = 0; for (int i = l; I <= mid; i++) if (Q[i].op = = 1) Lt[++ct1] = i; for (int i = mid + 1; I <= R; i++) if (Q[i].op = = 2) Lt[++ct1] = i; Sort (lt + 1, lt + ct1 + 1, cmpx); CDQ2 (1, CT1); CDQ (L, mid); CDQ (mid + 1, r);} int main () {int T; scanf ("%d", &t); while (t--) {scanf ("%d", &n); NX = NY = NZ = 0; m = 0; memset (ans, 0, sizeof (ans)); for (int i = 0; i < n; i++) {scanf ("%d", &op[i]); scanf ("%d%d%d", &xa[i], &ya[i], &za[i]); if (op[i] = = 1) {cx[nx++] = Xa[i]; cy[ny++] = Ya[i]; cz[nz++] = Za[i]; } else {scanf ("%d%d%d", &xb[i], &yb[i], &zb[i]); cx[nx++] = (--xa[i]); cy[ny++] = (--ya[i]); cz[nz++] = (--za[i]); cx[nx++] = Xb[i]; cy[ny++] = Yb[i]; cz[nz++] = Zb[i]; }} sort (CX, CX + NX); Sort (CY, Cy + NY); Sort (CZ, CZ + NZ); NX = Unique (CX, CX + NX)-CX; Ny = Unique (CY, CY + NY)-Cy; NZ = unique (CZ, CZ + NZ)-CZ; for (int i = 0; i < n; i++) {Xa[i] = Lower_bound (CX, CX + NX, Xa[i])-CX + 1; Ya[i] = Lower_bound (CY, Cy + NY, Ya[i])-cy + 1; Za[i] = Lower_bound (CZ, CZ + NZ, Za[i])-CZ + 1; if (op[i] = = 1) {Q[++m] = q (1, xa[i], ya[i], za[i]); } else {Xb[i] = Lower_bound (CX, CX + NX, Xb[i])-CX + 1; Yb[i] = Lower_bound (CY, Cy + NY, Yb[i])-cy + 1; Zb[i] = Lower_bound (CZ, CZ + NZ, Zb[i])-CZ + 1; Q[++m] = Q (2, Xb[i], yb[i], zb[i]); Q[++m] = Q (2, Xb[i], yb[i], za[i]); Q[++m] = Q (2, Xb[i], ya[i], zb[i]); Q[++m] = Q (2, Xa[i], yb[i], zb[i]); Q[++m] = Q (2, Xa[i], ya[i], zb[i]); Q[++m] = Q (2, Xa[i], yb[i], za[i]); Q[++m] = Q (2, Xb[i], ya[i], za[i]); Q[++m] = Q (2, Xa[i], ya[i], za[i]); }} CDQ (1, m); for (int i = 1; I <= m; i++) {if (Q[i].op = = 2) {printf ("%d\n", Ans[i]-ans[i + 1]-ans[i + 2]-ans[i + 3] + Ans[i + 4] + Ans[i + 5] + ans[i + 6]-ans[i + 7]); i + = 7; }}} return 0;}
Bestcoder #20