poj 3714 japan (分治)

題意:在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;
}
發佈了48 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章