题解:SP4226 MSE06H - Japan
有一说一,这题翻译太好了,害的我看了好久才看懂。
前置芝士
-
如何计算逆序对,不知道的话可以去 csdn 上查一下。
-
没了。
思路分析
所以这题还是很简单的对不对,只要读懂了就行。
先想一想什么时候可以相交,显然只有
很眼熟对不对,这不就是逆序对吗!
接下来就很简单了了,按
还有一点值得注意:多测不清空,爆零两行泪!
然后就可以愉快的通过此题了。
AC Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
char *p1,*p2,buf[1<<20+5];
inline int read(){
int x=0;
char c=gc();
while(!isdigit(c)){
c=gc();
}while(isdigit(c)){
x=x*10+(c^48);
c=gc();
}return x;
}
typedef long long LL;
const int N = 1000005;
int n, m, k;
int c[N];
LL res;
struct Kano
{
int x, y;
}a[N];
bool cmp(Kano a, Kano b)
{
if (a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
int lowbit(int x)
{
return x & (-x);
}
LL sum(int x)
{
LL sum = 0;
for (int i = x; i > 0; i -= lowbit(i)) sum += c[i];
return sum;
}
void upd(int x, int d)
{
for (int i = x; i <= n; i += lowbit(i)) c[i] += d;
}
void init()
{
res = 0;
memset(c, 0, sizeof c);
}
int main()
{
int T, f = 1;
T = read();
while (T -- )
{
init();
n = read(), m = read(), k = read();
for (int i = 1; i <= k; i ++ ) a[i].x = read(), a[i].y = read();
sort(a + 1, a + k + 1, cmp);
for (int i = k; i >= 1; i -- )
{
res += sum(a[i].y - 1);
upd(a[i].y, 1);
}
printf("Test case %d: %lld\n", f, res);
f ++ ;
}
return 0;
}