zoukankan      html  css  js  c++  java
  • [NOIP2012] 开车旅行

    传送门

    解答

    倍增。(确实没什么好说的)
    预处理时,懒得写链表,直接用set暴力维护……

    int n, h[maxn], x0, m, s[maxn], x[maxn];
    int near[maxn][2], f[maxn][maxlogn], g[maxn][maxlogn], sa[maxn][maxlogn], sb[maxn][maxlogn];
    set<pair<long long, int> > s;
    

    至于如何比较两个分数(可能有无穷大),对于(分子分母不全为零的)正分数(frac ab>frac AB)等价于(aB > Ab)(考虑第一象限向量的斜率与叉积即证)。

    代码

    #include <bits/stdc++.h>
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    
    const int maxn = 1e5+10, maxlogn = 20;
    
    typedef long long ll;
    typedef multiset<pair<long long, int> > Set;
    typedef Set::iterator It;
    
    int n, x0, m, s, x;
    long long h[maxn], g[maxn][maxlogn], sa[maxn][maxlogn], sb[maxn][maxlogn];
    int near[maxn][2], f[maxn][maxlogn];
    Set S;
    
    void go(ll s, ll x, ll &S, ll &SA, ll &SB) {
    //	printf(" %lld %lld
    ", s, x);
    	S = SA = SB = 0;
    	for (int k = maxlogn-1; ~k; --k)
    		if (S+g[x][k] <= s) {
    			S += g[x][k];
    			SA += sa[x][k];
    			SB += sb[x][k];
    			x = f[x][k];
    		}
    //	printf(" %lld %lld %lld %lld %lld
    ", s, x, S, SA, SB);
    }
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 0; i < n; ++i) {
    		scanf("%lld", h+i+1);
    	}
    	for (int i = 0; i < 2; ++i) {
    		S.insert(mp((ll)1e18, 0));
    		S.insert(mp((ll)-1e18, 0));
    	}
    	h[0] = -1e18;
    	for (int i = n; i; --i) {
    		It A = S.lower_bound(mp((ll)h[i], 0)), B = --A; ++A;
    		for (int j = 0; j < 2; ++j) {
    			near[i][j] = (A->fi-h[i] < h[i]-B->fi ? A++ : B--)->se;
    		}
    		S.insert(mp((ll)h[i], i));
    //		printf("%d %d
    ", near[i][0], near[i][1]);
    		f[i][0] = near[i][1];
    		g[i][0] = sa[i][0] = sa[i][1] = abs(h[f[i][0]]-h[i]);
    		f[i][1] = near[f[i][0]][0];
    		sb[i][1] = abs(h[f[i][1]]-h[f[i][0]]);
    		g[i][1] = sb[i][1]+sa[i][1];
    		for (int k = 2; k < maxlogn; ++k) {
    			int w = f[i][k-1];
    			f[i][k] = f[w][k-1];
    			g[i][k] = g[i][k-1]+g[w][k-1];
    			sa[i][k] = sa[i][k-1]+sa[w][k-1];
    			sb[i][k] = sb[i][k-1]+sb[w][k-1];
    		}
    //		for (int k = 0; k < maxlogn; ++k) printf("%lld %lld: %lld %lld %lld %lld
    ", i, k, f[i][k], g[i][k], sa[i][k], sb[i][k]);
    	}
    	scanf("%d%d", &x0, &m);
    	ll S, A, B, ansA = 1, ansB = 0, s0 = 0;
    	for (int i = 1; i <= n; ++i) {
    		go(x0, i, S, A, B);
    		if (!B) A = 1;
    		if (A*ansB < ansA*B || (A*ansB == ansA*B && h[i] > h[s0])) {
    			ansA = A;
    			ansB = B;
    			s0 = i;
    		}
    //		printf("  %lld %lld %lld
    ", ansA, ansB, s0);
    	}
    	printf("%lld
    ", s0);
    	for (int i = 0; i < m; ++i) {
    		scanf("%d%d", &x, &s);
    		go(s, x, S, A, B);
    		printf("%lld %lld
    ", A, B);
    	}
    }
    
  • 相关阅读:
    Android开发过程中遇到的问题集合(—)
    Android各种屏幕分辨率(VGA、HVGA、QVGA、WQVGA、WVGA、FWVGA) 具体解释
    Android中Context具体解释 ---- 你所不知道的Context
    HttpClient
    StretchDIBits使用方法
    int a[3];中a+1与&amp;a+1差别 -- C
    把质量控制工作往前推进(1)——安装sonarqube
    24点经典算法
    linux服务之udevd
    java实现第六届蓝桥杯星系炸弹
  • 原文地址:https://www.cnblogs.com/topsecret/p/11798564.html
Copyright © 2011-2022 走看看