poj 3067(树状数组)

来源:互联网 发布:淘宝开店不进货 编辑:程序博客网 时间:2024/06/07 17:29

题意:有两排城市,这两排之间有一些城市之间有连接的道路,给出所有道路,问有多少道路是相交的,交点不为城市所在点。

思路:开始暴力的做出来了,时间还挺短的,但知道这题可以用树状数组做,就做了一下。我们把所给的公路的坐标排序,按a升序,a相同按b升序。我们可以看出,每个点跟自己左上角和右下角的点都有交点,为了不重复统计,只统计每个点左上角的点数。就是求逆序数的个数,然后用点的个数减去就可以了。





#include<stdio.h>#include<stdlib.h>#include<string.h>const int N=1010;struct node{int x,y;}p[N*N];int S[N],n,m,k;void plus(int i){while(i<=m){S[i]++;i+=(i&(-i));}}__int64 findsum(int i){__int64 sum=0;while(i>0){sum+=S[i];i-=(i&(-i));}return sum;}int cmp(void const *a,void const *b){node *c,*d;c=(node *)a;d=(node *)b;if(c->x!=d->x)return c->x-d->x;return c->y-d->y;}int main(){int i,t,op=1;__int64 sum;scanf("%d",&t);while(t--){sum=0;memset(S,0,sizeof(S));scanf("%d%d%d",&n,&m,&k);for(i=1;i<=k;i++)scanf("%d%d",&p[i].x,&p[i].y);qsort(p+1,k,sizeof(p[0]),cmp);for(i=1;i<=k;i++){sum+=(i-1-findsum(p[i].y));plus(p[i].y);}printf("Test case %d: %I64d\n",op++,sum);}return 0;}

暴力代码:



#include<stdio.h>#include<string.h>const int N=1100;bool map[N][N];int b[N];int main(){int i,j,x,y,n,m,k,t,op=1;__int64 sum;scanf("%d",&t);while(t--){sum=0;scanf("%d%d%d",&n,&m,&k);memset(map,false,sizeof(map));memset(b,0,sizeof(b));for(i=1;i<=k;i++){scanf("%d%d",&x,&y);{map[x][y]=true;b[y]++;}}for(i=1;i<=n;i++){k=0;//j点上面所有点的边的数量for(j=1;j<=m;j++){if(map[i][j])//i,j之间有边{b[j]--;//去掉这条边sum+=k;}k+=b[j];}}printf("Test case %d: %I64d\n",op++,sum);}return 0;}


原创粉丝点击