POJ 2274
关于逆序数和堆的问题,这里很巧妙地从全局切入,即,每一次即将发生的超车,必定是超过他前面相邻的车(虽然具体到每一辆车,他不一定超过的就是他面前的车,但是要从全局考虑)。
- 之后维护堆有一点注意,因为堆不可以按照索引任意修改堆中元素,我们干脆就在堆中保留那些陈旧的节点,取出来的时候出现问题直接丢掉,而是去选择节点中记录的前一辆车信息,与我们实时更新的总表中前一辆车信息一致的节点。
- 每次更新的时候,就是唯一可能出现新的堆中节点的时候。
- 更新每辆车前面最近邻和后面最近邻的时候,类似于链表更新连接时的操作
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn= 25e4+5;
const int INF= 0x3f3f3f3f;
int a[maxn], b[maxn], x[maxn], v[maxn], vb[maxn], vt[maxn];
int inv;
struct T
{
int tu, td;
T(){}
T(int ttu, int ttd) : tu(ttu), td(ttd) {}
bool operator > (const T &z) const
{
return tu*z.td > td*z.tu;
}
bool operator == (const T &z) const
{
return tu*z.td == td*z.tu;
}
};
struct Record
{
int i;
int ai;
T t;
double mp;
Record(){}
Record(int ii, int aai, T tt) : i(ii), ai(aai), t(tt)
{
mp= x[i]+v[i]*1.0*t.tu/t.td;
}
bool operator < (const Record &z) const
{
if (t> z.t){
return true;
}
if (t== z.t && mp > z.mp){
return true;
}
return false;
}
};
priority_queue<Record> hp;
void Merge(int l, int r)
{
int m= (l+r)>>1;
int i= l, j= m+1;
int k= l;
while (i<= m && j<= r){
if (vb[i]> vb[j]){
vt[k++]= vb[j++];
inv+= m-i+1;
inv%= 1000000;
}
else{
vt[k++]= vb[i++];
}
}
while (i<= m){
vt[k++]= vb[i++];
}
while (j<= r){
vt[k++]= vb[j++];
}
for (i= l; i<= r; ++i){
vb[i]= vt[i];
}
}
void MergeSort(int l, int r)
{
if (l>= r){
return;
}
int m= (l+r)>>1;
MergeSort(l, m);
MergeSort(m+1, r);
Merge(l, r);
}
void Init(int n)
{
inv= 0;
memset(x, -1, sizeof(x));
memset(v, -1, sizeof(v));
v[n+1]= INF;
x[n+1]= 1e8;
}
int main()
{
int n, m, dv, dx;
T t;
scanf("%d", &n);
Init(n);
for (int i= 1; i<= n; ++i){
scanf("%d %d", x+i, v+i);
vb[i]= v[i];
a[i]= i+1;
b[i]= i-1;
}
for (int i= 1; i<= n; ++i){
dx= x[a[i]]-x[i];
dv= v[i]-v[a[i]];
if (dv > 0){
t= T(dx, dv);
hp.push(Record(i, a[i], t));
}
}
MergeSort(1, n);
cout<<inv<<endl;
m= inv > 10000 ? 10000 : inv;
while (m--){
Record tp= hp.top();
hp.pop();
while (tp.ai!= a[tp.i]){
tp= hp.top();
hp.pop();
}
a[b[tp.i]]= tp.ai;
b[a[tp.ai]]= tp.i;
a[tp.i]= a[tp.ai];
b[tp.ai]= b[tp.i];
a[tp.ai]= tp.i;
b[tp.i]= tp.ai;
dv= v[tp.i]- v[a[tp.i]];
if (dv > 0){
dx= x[a[tp.i]]- x[tp.i];
t= T(dx, dv);
hp.push(Record(tp.i, a[tp.i], t));
}
dv= v[b[tp.ai]]- v[tp.ai];
if (dv > 0){
dx= x[tp.ai]- x[b[tp.ai]];
t= T(dx, dv);
hp.push(Record(b[tp.ai], tp.ai, t));
}
printf("%d %d\n", tp.i, tp.ai);
}
return 0;
}