poj 3714 japan (分治)

来源:互联网 发布:api原油库存今天数据 编辑:程序博客网 时间:2024/05/20 18:00

题意:在Japan的东海岸和西海岸分别有n个城市和m个城市,分别编号为1..n和1..m。现在要修建k条高速路连接两岸的城市,告诉你这k座高速路连接的两边城市编号,请你计算,这些桥的交点数量。(在城市处的交点不算)

这道题就是求逆序对。将东边的城市按编号从小到大排序,然后分治寻找西边城市的编号的逆序对就可以了。注意排序时也要把西边的城市按升序排列。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n,m,k,times;struct data{    long long l,r;};data a[500002],t[500002];bool cmp(data a,data b){    if(a.l==b.l) return a.r<b.r;     return a.l<b.l;}long long fac(int x,int y){    if(x>=y) return 0;    int m=(x+y)>>1;    long long t1=fac(x,m);    long long t2=fac(m+1,y);    long long t3=0;    int i=x,e=x,j=m+1;    while(i<=m&&j<=y)    {        if(a[i].r>a[j].r)        {            if(a[i].l<a[j].l)  t3+=m-i+1;            t[e++]=a[j++];        } //t3+=j-m+1        else t[e++]=a[i++];    }    while(i<=m) t[e++]=a[i++];    while(j<=y) t[e++]=a[j++];    for(int i=x;i<=y;i++)    {        a[i]=t[i];    }    return t1+t2+t3;}int main(){    //freopen("1.txt","r",stdin);    scanf("%d",&times);    for(int j=1;j<=times;j++)    {        scanf("%d%d%d",&n,&m,&k);         for(int i=1;i<=k;i++)        {            scanf("%d%d",&a[i].l,&a[i].r);        }        sort(a+1,a+k+1,cmp);        long long ans=fac(1,k);        printf("Test case %d: %I64d\n",j,ans);    }    return 0;}
0 0