Enumeration refers to the upper and lower bounds of the enumeration matrix, and then finds the other intermediate 2 points according to P0, p1, p2 relationships. Then you need to memorize some places to prevent duplication and reduce the complexity of time. This should be the most critical step in optimizing time, referring to the to array in the code. Then is a sub-matrix of a calculation, need to use two-dimensional prefix and preprocessing data, and then judge the time of Direct O (1) query is good.
#include <bits/stdc++.h>using namespacestd;Const intINF =0x3f3f3f3f;Const intMAXN = 2e3 +7;structnode{intx, y; Node () {} node (intXinty): x (x), Y (y) {}}A[MAXN], B[MAXN], C[MAXN], x[4];intp[4], MATDP[MAXN][MAXN], to[maxn][2];BOOLCMP1 (ConstNode &a,ConstNode &b) { returnA.x <b.x;}BOOLCMP2 (ConstNode &a,ConstNode &b) { returnA.y >b.y;}BOOLCmp3 (ConstNode &a,ConstNode &b) { returnA.y <b.y;}intHowmany (intX1,intY1,intX2,inty2) { returnMATDP[X2][Y2] + matdp[x1-1][y1-1]-matdp[x1-1][Y2]-matdp[x2][y1-1];}BOOLIsOK () {intx1 = inf, y1 = inf, x2 =0, y2 =0; for(inti =0; I <4; i + +) {x1= Min (x1, x[i].x); x2 =Max (x2, x[i].x); Y1= Min (y1, x[i].y); y2 =Max (y2, x[i].y); for(intj = i +1; J <4; J + +) if((P[j]-p[i]) * (X[J].Y-X[I].Y) <=0)return false; } returnHowmany (x1, y1, x2, y2) = =4;}intMain () {intT, N, M, K, X, Y;SCANF ("%d",&T); while(T--) {scanf ("%d%d%d", &n, &m, &k); scanf ("%d%d%d%d", &p[0], &p[1], &p[2], &p[3]); intBig =0, small =0, ans =0; (p[0] > p[1]) ? Small + +: Big + +; (p[0] > p[2]) ? Small + +: Big + +; memset (MATDP,0,sizeof(MATDP)); for(inti =1; I <= K; i + +) {scanf ("%d%d", &x, &y); Matdp[x][y] =1; A[i]= B[i] = C[i] =node (x, y); } for(inti =1; I <= N; i + +){ for(intj =1; J <= M; J + +) Matdp[i][j]+ = Matdp[i][j-1]; for(intj =1; J <= M; J + +) Matdp[i][j]+ = Matdp[i-1][j]; } sort (A+1, A + K +1, CMP1); Sort (b+1, B + k +1, CMP2); Sort (c+1, C + k +1, Cmp3); for(inti =1; I <= K; i + +) {x[0] =A[i]; for(intj =0; J <= K; J + +) to[j][0] = to[j][1] = j = = k?0: J +1; for(intj = k; J > i; J--){ if(a[i].x = = a[j].x) Break; if((p[3]-p[0]) * (A[J].Y-A[I].Y) <=0)Continue; x[3] = A[j]; x[1] = x[2] = node (-1, -1); intU =0, V, bi = big, SM = small, t =1; while(SM--){ for(v = u, u = to[u][0]; U to[v][0] = to[u][0], v = u, u = to[u][0]) if(A[i].x < b[u].x && b[u].x < a[j].x && B[u].y <a[i].y) {x[t+ +] = B[u]; Break; }} u=0; while(Bi--){ for(v = u, u = to[u][1]; U to[v][1] = to[u][1], v = u, u = to[u][1]) if(A[i].x < c[u].x && c[u].x < a[j].x && c[u].y >a[i].y) {x[t+ +] = C[u]; Break; } } if(T <3|| x[1].x = = x[2].x)Continue; if(x[1].x > x[2].x) Swap (x[1], x[2]); if(IsOK ()) ans + +; }} printf ("%d\n", ans); } return 0;}
Memento Mori (two-dimensional prefix and + enumeration pruning)