邓俊辉老师数据结构课后练习-灯塔LightHouse

题目地址:https://dsa.cs.tsinghua.edu.cn/oj/problem.shtml?id=1144提交的结果
惭愧

#include <cstdio>
#include<iostream>

using namespace std;
typedef long long LL;
const int MAX=4000000;
const LL M=0xFFFFFFFL;
LL co[MAX];
LL v[MAX];
LL inversion=0;

void invBetween(LL vv[],int lo,int mi,int hi){
    int lb=mi-lo;
    int lc=hi-mi;
    LL *a=vv+lo;
    LL *c=vv+mi;
    LL *b=new LL[lb];
    for(int i=0;i<lb;i++){
        b[i]=a[i];
    }
    for(int i=0,j=0,k=0;j<lb;){
        if(lc<=k||b[j]<=c[k]){
            a[i++]=b[j++];
        }
        else{
            a[i++]=c[k++];
            inversion=inversion+(lb-j);
        }
    }
    delete []b;//有几次提交90,95,就是这个忘了,惭愧
}
void invInside(LL vv[],int lo,int hi){
    if(hi-lo<2)return ;
    int mi=(lo+hi)>>1;
    invInside(vv,lo,mi);
    invInside(vv,mi,hi);
    invBetween(vv,lo,mi,hi);
}


int main()
{
    int n;
    LL x,y;
    LL c;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%lld%lld",&x,&y);
        co[i]=(x<<28)+y;//10^8小于2^28次方,所以左移了28位,正好7个F。把x和y拼到一起
    }

    invInside(co,0,n);//x左移28,所以co排序结果跟对x排序是一样的。记得这个调用会改变全局变量inversion。

    for(int i=0;i<n;i++){
        v[i]=(co[i]&M);//x已经排好序了,把y取出来,求逆序。
    }
    inversion=0;//好几次忘了把这个逆序重新置零

    invInside(v,0,n);
    LL N=(LL)n;//直接用n去算n*(n-1)/2,会出错,提交40,45,50分的基本都是这个原因
    LL cc=N*(N-1)/2;
    printf("%lld\n",cc-inversion);//总对数-逆序对就是互相能照到的灯对。
    return 0;
}

哎呀,这么简单,我搞了半天,各种小问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值