poj3067 Japan 树状数组&逆序对

     理解题意候会发现这就是一道求逆序对的题目。以a为第一关键字,b为第二关键字按照升序对原始输入数据进行排序,然后对每个b,检查前面比它大的有几个。

 

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>

using namespace std;
struct way
{
    int a,b;
    bool operator<(const struct way t)const
    {
        return a<t.a||a==t.a&&b<t.b;
    }
}p[1000005];
int c[1005],t,n,m,k;

inline int lowbit(int k)
{
    return k&(-k);
}

void insert(int i,int d)
{
    while(i<=m)
    {
        c[i]+=d;
        i+=lowbit(i);
    }
}

int getsum(int i)
{
    int t=0;
    while(i)
    {
        t+=c[i];
        i-=lowbit(i);
    }
    return t;
}

int main()
{
    scanf("%d",&t);
    int C=1;
    __int64 sum;
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++)
            scanf("%d%d",&p[i].a,&p[i].b);
        sort(p,p+k);
        sum=0;
        memset(c,0,sizeof(int)*(m+1));
        for(int i=0;i<k;i++)
        {
            sum+=getsum(m)-getsum(p[i].b);
            insert(p[i].b,1);
        }
        printf("Test case %d: %I64d\n",C++,sum);
    }
    return 0;
}


 

你可能感兴趣的:(poj3067 Japan 树状数组&逆序对)