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 ;
}