###题目: Poj 3067 Japan
### 题解:
1.求逆序对
2.bit
3.先排前端,再排后端,提取后端序列
4.wrong 到发疯~~~
for (LL u = f[i]; u <= M; u += u & ((-1)*u)) c[u] ++;
和
void add(LL i, LL x)
{
while (i <= M)//注意M而不是K或N
{
bit[i] += x;
i += i & -i;
}
}
###AC代码:
####解1
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#define maxn 1000000 + 10
using namespace std;
typedef long long LL;
int f[maxn],c[maxn];
int N,M,K;
struct P{
int w;
int e;
};
P cnt[maxn];
bool cmp ( const P &a,const P &b)
{
if (a.w == b.w) return a.e < b.e;
else return a.w < b.w;
}
int main()
{
int T;
cin >> T;
for (int t = 1; t <= T; t++)
{
scanf("%d%d%d",&N,&M,&K);
for(int k = 0; k < K; k++)
scanf("%d%d",&cnt[k].w,&cnt[k].e);
sort (cnt,cnt+K,cmp);
memset (c,0,sizeof(c));
int num = 0;
LL ans = 0;
for (int i = 0; i < K; i++)
{
num ++;
f[num] = cnt[i].e;
}
for (int i = 1; i <= num; i++)
{
ans += i - 1;
for (LL u = f[i];u > 0; u -= u & ((-1)*u)) ans -= c[u];
for (LL u = f[i]; u <= M; u += u & ((-1)*u)) c[u] ++;
}
printf("Test case %d: %lld\n",t,ans);
}
return 0;
}
####解2
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1000000 + 10;
LL bit[1010];
LL n;
LL N,M,K;
struct P{
LL w;
LL e;
};
P cnt[maxn];
bool cmp (P a,P b)
{
if (a.w == b.w) return a.e < b.e;
else return a.w < b.w;
}
LL sum(LL i)
{
LL s = 0;
while(i > 0)
{
s += bit[i];
i -= i & -i;
}
return s;
}
void add(LL i, LL x)
{
while (i <= M)
{
bit[i] += x;
i += i & -i;
}
}
int main()
{
LL T;
cin >> T;
for (LL t = 1; t <= T; t++)
{
memset(cnt,0,sizeof(cnt));
scanf("%I64d%I64d%I64d",&N,&M,&K);
for(LL i = 1; i <= K; i++)
scanf("%I64d%I64d",&cnt[i].w,&cnt[i].e);
sort (cnt+1,cnt+K+1,cmp);
LL ans = 0;
memset (bit,0,sizeof(bit));
n = K;
for (LL i = 1; i <= n; i++)
{
ans += i - 1 - sum(cnt[i].e);
add(cnt[i].e,1);
}
printf("Test case %I64d: %I64d\n",t,ans);
}
return 0;
}