您的位置:首页 > 其它

POJ 3067 Japan

2014-08-15 13:48 190 查看
//树状数组
//转换为求逆序对
//排序原理:其计算的是对于当前第 i 条边来说( Xi, Yi ),要计算对于 Y > Yi ( X < Xi )的所有逆序对数目。右边部分也要进行从小到大排序,因为对于( x, ya ),( x, yb ),( ya < yb ) 如果先处理(x,yb)则逆序数会多加一次。如果先处理(x,ya),则认为是没有交点的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 2000;
typedef long long ll;
int n;
int bit[maxn<<1];
int crt[maxn<<1];
struct po{
    int x;
    int y;
}p[maxn*maxn];
int cmp(const po&a,const po&b){  
    if(a.x!=b.x)
        return a.x<b.x;
    else return a.y<b.y;   
}

void add(int i,int x){
    while(i<=maxn){         
        bit[i] +=x;
        i += i&(-i);
    }
}

ll sum(int x){
    ll res=0;
    while(x>0){
        res +=bit[x];
        x -= x&(-x);
    }
    return res;
}

int main()
{
  //  freopen("in.txt","r",stdin);
    int m,k,T;
    scanf("%d",&T);
    for(int t=1;t<=T;++t){
        memset(bit,0,sizeof(bit));   //这里必须对bit初始化,WA了好多下
        scanf("%d%d%d",&n,&m,&k);
        int maxm = 0;
        for(int i=0;i<k;++i){
            scanf("%d%d",&p[i].x,&p[i].y);
            if(maxm<p[i].y)maxm = p[i].y;
        }
        sort(p,p+k,cmp);
        ll res = 0;
        for(int i=0;i<k;++i){
            add(p[i].y,1);
            res +=sum(maxm)-sum(p[i].y);
        }
        printf("Test case %d: %lld\n",t,res);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: