• 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
    ", tp.i, tp.ai);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    HDU-ACM课堂作业 Degree Sequence of Graph G & Frogs' Neibroghood
    HDU-ACM课堂作业 Least Common Multiple
    HDUOJ 悼念512汶川大地震遇难同胞——老人是真饿了
    HDUOJ 1236 排名
    HDUOJ Quicksum
    HDUOJ 2560 The Seven Percent Solution
    1255 迷宫问题
    1253 抓住那头牛
    1254 走出迷宫
    1252:走迷宫
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/13330666.html
Copyright © 2020-2023  润新知