Topic Links:
http://poj.org/problem?id=3067
Main topic:
There are two rows of cities, a row of N cities, numbered 1~n, a row of M cities, numbered 1~m. There are K roads between the two rows of cities.
The road is connected in a straight line, Q: How many roads are intersected by these roads, and the focus is not the point at which the city resides, find the number of intersections.
Ideas:
The idea of a tree-like array. Refer to the diagram on the net, first the all edges (u,v) in ascending order of U, if you are the same, in ascending order of V. Can
To see, the Road (U1,V1) and the road (U2,V2) If there are intersections, U1 > U2 and V1 < v2, or U1 < U2 and
V1 > V2, in order to not repeat the calculation, ignoring the latter case. If you have finished sorting, you can see: The result is the inverse of the right sequence
Ordinal. Directly establish the tree array to find the reverse number.
For example, as shown in the example in question. The order of completion is:
1 4
2 3
3 1
3 2
The number of intersections is: 0+1+2+2 = 5.
AC Code:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #define LL __ int64using namespace Std;const int maxn = 1000;int tree[maxn+10];struct node{int u,v;} Edges[maxn*maxn];int CMP (Node A,node b) {if (a.u! = b.u) return a.u < b.u; else return A.V < B.V;} int lowbit (int x) {return x & (-X);} void Update (int i,int x) {while (I <= MAXN) {Tree[i] + = x; i + = Lowbit (i); }}ll Query (int n) {LL sum = 0; while (n > 0) {sum + = Tree[n]; N-= Lowbit (n); } return sum;} int main () {int t,n,m,k,kase = 0; scanf ("%d", &t); while (t--) {memset (tree,0,sizeof (Tree)); scanf ("%d%d%d", &n,&m,&k); for (int i = 0; i < K; ++i) scanf ("%d%d", &EDGES[I].U,&EDGES[I].V); Sort (edges,edges+k,cmp); LL ans = 0; for (int i = 0; i < K; ++i) {ans + = i-query (EDGES[I].V); Update (EDGes[i].v,1); } printf ("Test Case%d:%i64d\n", ++kase, ans); } return 0;}
POJ3067 Japan "Tree array" "Reverse order Number"