You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <cstdio>
# include <string.h>
# include <algorithm>
# include <iostream>
using namespace std ;
typedef long long LL ;
const int N = 1e6 + 10 ;
int n , m ;
struct Node {
int l , r ;
const bool operator < ( const Node & t ) const {
if ( l = = t . l ) return r < t . r ;
return l < t . l ;
}
} q [ N ] ;
// 树状数组模板
typedef long long LL ;
# define lowbit(x) (x & -x)
int c [ N ] ;
void add ( int x , int d ) {
for ( int i = x ; i < N ; i + = lowbit ( i ) ) c [ i ] + = d ;
}
LL sum ( int x ) {
LL res = 0 ;
for ( int i = x ; i ; i - = lowbit ( i ) ) res + = c [ i ] ;
return res ;
}
int main ( ) {
# ifndef ONLINE_JUDGE
freopen ( " POJ3067.in " , " r " , stdin ) ;
# endif
int T ;
scanf ( " %d " , & T ) ;
int cnt = 0 ;
while ( T - - ) {
memset ( c , 0 , sizeof c ) ;
int k ;
scanf ( " %d %d %d " , & n , & m , & k ) ; // 左右两边分别有n和m个城市, 然后k行给出连边, 问共有多少交叉点
for ( int i = 1 ; i < = k ; i + + ) scanf ( " %d %d " , & q [ i ] . l , & q [ i ] . r ) ;
sort ( q + 1 , q + 1 + k ) ; // 按左端点由小到大,右端点由小到大排序
// 没有离散化
// Q:为什么这里不使用离散化呢?为什么前一题 一维逆序对的数量就要使用离散化呢?
// 答: 因为前一题的数值1e9,而个数是1e5,所以需要映射到1~1e5的空间上, 再用二分快速找出相对位置
// 而本题, 数值l,r 与 个数其实是一个概念, 都是小于等于1000的, 无需离散化。
LL res = 0 ;
for ( int i = 1 ; i < = k ; i + + ) { // 捋着原数组来,也就是一条边一条边来,逐个进入树状数组
// 当i号边进入树状数组时, 在它前面进入的, 肯定是左端点比自己小的, 也就是值比自己小,
// 那么,就检查出现的位置,也就是对应的出现在自己右侧的端点个数
res + = sum ( m ) - sum ( q [ i ] . r ) ; // 注意这里的sum(m),因为考查的是右端点, 而右端点的上限是m
add ( q [ i ] . r , 1 ) ;
}
printf ( " Test case %d: %lld \n " , + + cnt , res ) ;
}
return 0 ;
}