Luogu P1966 火柴排队

由排序不等式知离散化后\(rka_i = rkb_+i\)

首先对于序列进行离散化,这里学到了一招:

for(int i=1;i<=n;++i) scanf("%d",&a[i]) , rka[i] = i ;
for(int i=1;i<=n;++i) scanf("%d",&b[i]) , rkb[i] = i ;
sort(rka+1,rka+1+n,cmp1) ; sort(rkb+1,rkb+1+n,cmp2) ;

正确性显然

然后设\(q_{a_i} = b_i\) ,那么对于每个\(a_i\),若{a}={b},则应由\(q_i = a_i\) , 即整个序列按升序排列,需要次数为逆序对个数

Code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#define _ 1000005
#define Mod 99999997
using namespace std ;
int a[_] , b[_] , n , rka[_] , rkb[_] , q[_] ;
namespace fenwickTree {
    int vec[_];

    inline int lowbit(int x) {
        return x & (-x);
    }

    inline void modify(int id, int x) {
        while (id <= n) {
            vec[id] += x;
            id += lowbit(id);
        }
    }

    inline int query(int id) {
        int res = 0;
        while (id >= 1) {
            res += vec[id];
            id -= lowbit(id);
        }
        return res;
    }
}
using namespace fenwickTree;

inline bool cmp1(int i, int j) {
    return a[i] < a[j];
}

inline bool cmp2(int i, int j) {
    return b[i] < b[j];
}
int main(){
    scanf("%d",&n) ;
    for(int i=1;i<=n;++i) scanf("%d",&a[i]) , rka[i] = i ;
    for(int i=1;i<=n;++i) scanf("%d",&b[i]) , rkb[i] = i ;
    sort(rka+1,rka+1+n,cmp1) ; sort(rkb+1,rkb+1+n,cmp2) ;
    for(int i=1;i<=n;++i) q[rka[i]] = rkb[i] ;
    int ans = 0 ; 
    for(int i=n;i>=1;--i){
        ans += query(q[i]-1) ; modify(q[i],1) ; ans%=Mod ;
    }
    cout<<ans%Mod<<endl ;
}

转载于:https://www.cnblogs.com/tyqtyq/p/10872260.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值