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 ;
}
posted @ 2019-05-15 21:15  tyqtyq~!  阅读(122)  评论(0编辑  收藏  举报