POJ-3067-树状数组

来源:互联网 发布:数据分析员培训 编辑:程序博客网 时间:2024/06/06 00:45

题目大意:东边有n座城市,西边有m座城市,现在连k跳线,问他们中有几个交点;

题目解析:就是逆序对的问题,注意答案要开long long并且如果两条线段如果起点或者终点相同是不算的,这样的话先按东边的点升序排序,相同的话按照西边的点排序,然后枚举的时候统计比西边城市比他大的点,再更新;

AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int maxn=1010;struct node{    int l,r,index;}q[maxn*maxn];bool cmp(node a,node b){    if(a.l==b.l)    return a.r<b.r;    return a.l<b.l;}int lowbit(int k){    return k&(-k);}int d[1010],n,m;ll getsum(int h){    ll sum=0;    for(int i=h+1;i<=m;i+=lowbit(i))        sum+=d[i];    return sum;}void update(int h){    for(int i=h;i>=1;i-=lowbit(i))        d[i]++;}int main(){    int cas,cc=1,k;    scanf("%d",&cas);    while(cas--)    {        scanf("%d%d%d",&n,&m,&k);        memset(d,0,sizeof(d));        for(int i=0;i<k;i++)        {            scanf("%d%d",&q[i].l,&q[i].r);            q[i].index=i;        }        sort(q,q+k,cmp);        ll ans=0;        for(int i=0;i<k;i++)        {            ans+=getsum(q[i].r);            update(q[i].r);        }        printf("Test case %d: %lld\n",cc++,ans);    }    return 0;}


0 0