題解 SP4226 【MSE06H - Japan】(樹狀數組+逆序對)

原OJ提交點這裏node

題目描述

 

日本計劃迎接ACM-ICPC世界總決賽,爲此必須修建大量道路。日本是一個高島,東海岸有N個城市,西海岸有M個城市(M <= 1000, N <= 1000)。將修建K條高速公路。每一個海岸的城市編號分別是一、二、……從北到南。每條高速公路都是一條直線,鏈接着東海岸的城市和西海岸的城市。建設資金由ACM擔保。其中很大一部分是由高速公路之間的交叉點數量決定的。兩條高速公路最多在一個地點相交。編寫一個程序,計算高速公路之間的交叉點數量。ios

分析數組

 

這道題一開始讓我很霧......spa

不過 思路其實很是清晰:若是i<j a[i].x<a[j].x a[i].y>a[j].y 那麼就會產生一個交點 你們畫個圖就出來了code

具體操做也很好實現:blog

定義一個結構體 x升序排列 當x相同就y升序排列排序

按照咱們的排序方式 把a[i].y踢出來跑樹狀數組求逆序對就能夠了get

附上AC代碼string

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1005;
int l,n,m,k,c[1005],a[1005];
long long ans=0;
struct nodee
{
    int x,y;
}qwq[N*N];
int lowbit(int x)
{
    return x&-x;
}
void add(int pos,int x)
{
    for(int i=pos;i<=n;i+=lowbit(i))
    {
        c[i]+=x;
    }
}
int query(int pos)
{
    long long sum=0;
    for(int i=pos;i>=1;i-=lowbit(i))
    {
        sum+=c[i];
    }
    return sum;
}
bool cmp(nodee a,nodee b)
{
    return (a.x<b.x)||((a.x==b.x)&&(a.y<b.y));
}
int main()
{
    scanf("%d",&l);
    for(int i=1;i<=l;i++)
    {
        memset(c,0,sizeof(c));
        memset(a,0,sizeof(a));
        scanf("%d%d%d",&n,&m,&k);
        for(int j=1;j<=k;j++)
        {
            scanf("%d%d",&qwq[j].x,&qwq[j].y);
        }
        sort(qwq+1,qwq+1+k,cmp);    
        ans=0;                                                                                                    
        for(int j=k;j>=1;j--)
        {
            add(qwq[j].y,1);
            ans+=query(qwq[j].y-1);
        }
    printf("Test case %d: %lld\n",i,ans);
    }
    return 0;
}

最後仍是要插兩句 我開始的逆序對用了離散化 而且在最後求逆序對跑的順序 不知道爲何 在luogu,Virtual Judge和POJ都是RE,後來還變成了TLE(好過度嚶嚶嚶) 我不知道這是怎麼肥四! 這道題應該能夠跑歸併 我沒有嘗試 你們有興趣能夠試試 貼一下我RE的代碼 至今不知道錯在哪 歡迎大佬指正it

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=10005;
int l,n,m,k,c[N],a[N];
long long ans=0;
struct node
{
    int tot,num;
}qaq[N];
struct nodee
{
    int x,y;
}qwq[N];
int lowbit(int x)
{
    return x&-x;
}
void add(int pos,int x)
{
    for(int i=pos;i<=1005;i+=lowbit(i))
    {
        c[i]+=x;
    }
}
int query(int pos)
{
    long long sum=0;
    for(int i=pos;i>=1;i-=lowbit(i))
    {
        sum+=c[i];
    }
    return sum;
}
bool cmp(nodee a,nodee b)
{
    return (a.x<b.x)||((a.x==b.x)&&(a.y<b.y));
}
bool cmpp(node a,node b)
{
    return a.tot<b.tot;
}
int main()
{
    scanf("%d",&l);
    for(int i=1;i<=l;i++)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int j=1;j<=k;j++)
        {
            scanf("%d%d",&qwq[j].x,&qwq[j].y);
        }
        sort(qwq+1,qwq+1+k,cmp);
        for(int j=1;j<=k;j++)
        {
            qaq[j].tot=qwq[j].y;
            qaq[j].num=j;
        }
        sort(qaq+1,qaq+1+k,cmpp);
        for(int j=1;j<=k;j++)
        {
            a[qaq[j].num]=j;
        }
        ans=0;
        for(int j=1;j<=k;j++)
        {
            add(a[j],1);
            ans+=(j-query(a[j]));
        }
    printf("Test case %d: %lld\n",i,ans);
    }
    return 0;
}
相關文章
相關標籤/搜索