P1966 火柴排队题解

P1966 火柴排队

题意:有两列火柴,各有各的高度,两两高度不同,每次只能交换相邻的数,问最少交换多少次,使得 ∑ ( a i − b i ) 2 \sum (a_i-b_i)^2 (aibi)2最小。

解法:离散化+树状数组!
因为数据各不相同,可以想到最优的情况一定是最小的对应第二组的最小的,次小的对应次小的,…,那么可以清楚这题跟数字的大小无关,只和相对大小有关,那么能想到离散化,这里是离散化的两种方法,刚开始理解的时候,会错了意思,以为离散化以后,只是把离散化后的值采取p[a[i]]=b[i],所以采用了第二种方法,但是第二种方法离散化以后,不能访问到原数组的下标。仔细想了一下,因为是需要求交换次数的,要展现出相对大小的同时,还要知道原数组中第一小的值位置在哪,第二小的值位置在哪,那么第二种离散化方式用在这题就是错的(只过了一个点)。

代码

#include  <algorithm>
#include  <iostream>
#include  <cstring>
#include  <vector>
#include  <cstdio>
#include  <queue>
#include  <cmath>
#include  <set>
#include  <map>
#include  <bitset>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-4
#define rint register int
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<LL, int> mli;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
    
    
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') {
    
     if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') {
    
     res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int ne[8][2] = {
    
    1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const LL INF = 1e18;
const int N = 1e5+10;
const LL Mod = 99999997;
const int M = 110;
LL tmp[N], c[N];
int n, cnt;
LL tr[N];
int lowbit(int x) {
    
     return x & -x; }
void upd(int p, LL d) {
    
    
  for( ; p <= n; p += lowbit(p) ) tr[p] = (tr[p] + d) % Mod;
}
LL que(int p) {
    
    
  LL r = 0;
  for( ; p > 0; p -= lowbit(p) ) r = (r + tr[p]) % Mod;
  return r;
}
struct xx {
    
    
  int v, id;
  bool operator < (const xx &c) const {
    
    
    return v < c.v;
  }
}a[N], b[N];
int main() {
    
    
  scanf("%d", &n);
  _rep(1, n, i) {
    
     scanf("%lld", &a[i].v); a[i].id = i; }
  _rep(1, n, i) {
    
     scanf("%lld", &b[i].v); b[i].id = i; }
  sort(a+1, a+n+1); sort(b+1, b+n+1);
  _rep(1, n, i) c[a[i].id] = b[i].id;
  LL ans = 0;
  _rep(1, n, i)  {
    
    
    upd(c[i], 1); ans = (ans + i - que(c[i]))%Mod;
  }
  printf("%lld\n", ans);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43408978/article/details/108988078