做水题好爽...
展开式子
就是最大化\(2*a_i*b_i\)
显然令大的乘大的能最大化上式
相当于用最小步数把1序列转化为2序列
映射后求逆序对.
#include<cstdio>
#include<cstring>
#include<algorithm>
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
const int maxn = 100007;
#define lowbit(x) (x & (- x))
#define mod 99999997
int n ;
struct C {
int v,id;
C (int v = 0,int id = 0) : v(v),id(id) {};
bool operator < (const C &a)const {
return v < a.v;
}
} a[maxn],b[maxn];
int has[maxn],tree[maxn << 2];
void update(int x) {for(;x <= n;tree[x] += 1,x += lowbit(x));}
int query(int x) {int ret = 0;for(;x >= 1;ret += tree[x],x -= lowbit(x));return ret;}
int main() {
n = read();
for(int i = 1;i <= n;++ i) a[i] = C(read(),i);
for(int i = 1;i <= n;++ i) b[i] = C(read(),i);
std::sort(a + 1,a + n + 1);
std::sort(b + 1,b + n + 1);
for(int i = 1;i <= n;++ i) has[a[i].id] = b[i].id;
int ans = 0;
for(int i = 1;i <= n;++ i) {
update(has[i]);
ans =(ans + i - query(has[i])) % mod;
}
printf("%d\n",ans);
return 0;
}