您的位置:首页 > 其它

luogu P1966 火柴排队

2018-04-28 20:38 127 查看
做水题好爽...

展开式子

就是最大化\(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: