zoukankan      html  css  js  c++  java
  • Luogu1081 开车旅行

    代码巨长的倍增题...

    显然这是没有什么决策的,选择方案都是固定的

    这可以考虑倍增跳,每个位置上跳到的位置是可以通过查前驱后继解决的

    有两种方式:

      一种是平衡树搞法,倒着做查完了插入

      另一种是先排序建一个链表,查完了删除

    都是可以通过加哨兵节点来搞的,
    结果我只想到了 set 乱搞,就写了很长

    预处理完就可做了

    第一问对于每个点倍增一遍,其实就是照题意模拟,倍增优化一下

    第二问还是照题意模拟,倍增优化一下

    暴力有 70pts ?


    代码:

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cstdio>
    #include <locale>
    #include <cmath>
    #include <set>
    using namespace std;
    
    typedef long long ll;
    const int MAX_N = 100005;
    const double INF = 100000000000001.0;
    
    struct Node {
    	int len, id;
    	Node(int L = 0, int ID = 0) {len = L; id = ID;}
    	bool operator < (const Node& b) const {
    		return len < b.len;
    	}
    };
    struct PAIR {
    	ll fir, sec;
    	PAIR(ll x = 0, ll y = 0) {fir = x; sec = y;}
    	friend PAIR operator + (PAIR a, PAIR b) {
    		return PAIR(a.fir + b.fir, a.sec + b.sec);
    	}
    }d[MAX_N][20][2];
    int n, lg, x0, m, ans;
    
    int h[MAX_N], f[MAX_N][20][2];
    double ans_rat;
    set<Node> st;
    
    inline int rd() {
    	register int x = 0, c = getchar();
    	register bool f = false;
    	while (!isdigit(c)) {
    		f = (c == '-');
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		x = x * 10 + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    inline void get_for(int pos, set<Node>::iterator iter) {
    	auto lef = iter, rig = iter;
    	if (iter == st.begin()) {
    		f[pos][0][0] = iter->id;
    		d[pos][0][0].fir = abs(h[pos] - h[iter->id]);
    		++iter;
    		if (st.size() == 1) return;
    		f[pos][0][1] = iter->id;
    		d[pos][0][1].sec = abs(h[pos] - h[iter->id]);
    		return;
    	} else if (iter == st.end()) {
    		--iter;
    		f[pos][0][0] = iter->id;
    		d[pos][0][0].fir = abs(h[pos] - h[iter->id]);
    		if (iter == st.begin()) return;
    		--iter;
    		f[pos][0][1] = iter->id;
    		d[pos][0][1].sec = abs(h[pos] - h[iter->id]);
    		return;
    	}
    	++rig;
    	if (rig == st.end()) {
    		--lef;
    		if (lef == st.begin()) {
    			if (abs(h[pos] - h[lef->id]) <= abs(h[pos] - h[iter->id])) {
    				f[pos][0][0] = lef->id;
    				d[pos][0][0].fir = abs(h[pos] - h[lef->id]);
    				f[pos][0][1] = iter->id;
    				d[pos][0][1].sec = abs(h[pos] - h[iter->id]);
    			} else {
    				f[pos][0][0] = iter->id;
    				d[pos][0][0].fir = abs(h[pos] - h[iter->id]);
    				f[pos][0][1] = lef->id;
    				d[pos][0][1].sec = abs(h[pos] - h[lef->id]);
    			}
    			return;
    		}
    		if (abs(h[pos] - h[lef->id]) <= abs(h[pos] - h[iter->id])) {
    			f[pos][0][0] = lef->id;
    			d[pos][0][0].fir = abs(h[pos] - h[lef->id]);
    			--lef;
    			if (abs(h[pos] - h[lef->id]) <= abs(h[pos] - h[iter->id])) {
    				f[pos][0][1] = lef->id;
    				d[pos][0][1].sec = abs(h[pos] - h[lef->id]);
    			} else {
    				f[pos][0][1] = iter->id;
    				d[pos][0][1].sec = abs(h[pos] - h[iter->id]);
    			}
    			return;
    		}
    		f[pos][0][0] = iter->id;
    		d[pos][0][0].fir = abs(h[pos] - h[iter->id]);
    		f[pos][0][1] = lef->id;
    		d[pos][0][1].sec = abs(h[pos] - h[lef->id]);
    		return;
    	}
    	--lef;
    	if (abs(h[pos] - h[lef->id]) == abs(h[pos] - h[iter->id])) {
    		f[pos][0][0] = lef->id;
    		d[pos][0][0].fir = abs(h[pos] - h[lef->id]);
    		f[pos][0][1] = iter->id;
    		d[pos][0][1].sec = abs(h[pos] - h[iter->id]);
    	} else if (abs(h[pos] - h[lef->id]) < abs(h[pos] - h[iter->id])) {
    		f[pos][0][0] = lef->id;
    		d[pos][0][0].fir = abs(h[pos] - h[lef->id]);
    		if (lef == st.begin()) {
    			f[pos][0][1] = iter->id;
    			d[pos][0][1].sec = abs(h[pos] - h[iter->id]);
    		} else {
    			--lef;
    			if (abs(h[pos] - h[lef->id]) <= abs(h[pos] - h[iter->id])) {
    				f[pos][0][1] = lef->id;
    				d[pos][0][1].sec = abs(h[pos] - h[lef->id]);
    			} else {
    				f[pos][0][1] = iter->id;
    				d[pos][0][1].sec = abs(h[pos] - h[iter->id]);
    			}
    		}
    	} else {
    		f[pos][0][0] = iter->id;
    		d[pos][0][0].fir = abs(h[pos] - h[iter->id]);
    		if (abs(h[pos] - h[lef->id]) <= abs(h[pos] - h[rig->id])) {
    			f[pos][0][1] = lef->id;
    			d[pos][0][1].sec = abs(h[pos] - h[lef->id]);
    		} else {
    			f[pos][0][1] = rig->id;
    			d[pos][0][1].sec = abs(h[pos] - h[rig->id]);
    		}
    	}
    }
    inline void DBL_init() {
    	for (int i = n; i >= 1; --i) {
    		if (!st.empty()) {
    			auto dst = st.lower_bound(h[i]);
    			get_for(i, dst);
    		}
    		st.insert(Node(h[i], i));
    	}
    	for (int i = 1; i <= n && 2 + i <= n; ++i) {
    		f[i][1][0] = f[f[i][0][0]][0][1];
    		f[i][1][1] = f[f[i][0][1]][0][0];
    		d[i][1][0] = d[i][0][0] + d[f[i][0][0]][0][1];
    		d[i][1][1] = d[i][0][1] + d[f[i][0][1]][0][0];
    	}
    	for (int j = 2; j <= lg; ++j) {
    		for (int i = 1; i <= n && (1 << j) + i <= n; ++i) {
    			f[i][j][0] = f[f[i][j - 1][0]][j - 1][0];
    			f[i][j][1] = f[f[i][j - 1][1]][j - 1][1];
    			d[i][j][0] = d[i][j - 1][0] + d[f[i][j - 1][0]][j - 1][0];
    			d[i][j][1] = d[i][j - 1][1] + d[f[i][j - 1][1]][j - 1][1];
    		}
    	}
    }
    inline void get_ans(int bgn) {
    	register int pos = bgn;
    	register ll dst_a = 0, dst_b = 0;
    	register bool got_bgn = false;
    	register double rat;
    	for (int i = lg; i >= 0; --i) {
    		if (!f[pos][i][1] || dst_a + dst_b + d[pos][i][1].fir + d[pos][i][1].sec > x0 || (i == 0 && !f[pos][0][0])) continue;
    		got_bgn = true;
    		dst_b += d[pos][i][1].fir;
    		dst_a += d[pos][i][1].sec;
    		pos = f[pos][i][1];
    	}
    	if (!got_bgn) return;
    	if (dst_b == 0) {
    		if (dst_a == 0) rat = 1.0;
    		else rat = INF;
    	} else {
    		rat = double(dst_a) / double(dst_b);
    	}
    	if (fabs(0.0 - ans_rat) < 1e-7 || rat < ans_rat || (fabs(rat - ans_rat) < 1e-7 && h[bgn] > h[ans])) {
    		ans_rat = rat;
    		ans = bgn;
    	}
    }
    
    int main() {
    	n = rd();
    	lg = int(ceil(log2(n)));
    	for (int i = 1; i <= n; ++i) h[i] = rd();
    	DBL_init();
    	x0 = rd();
    	for (int i = 1; i <= n; ++i)
    		get_ans(i);
    	printf("%d
    ", ans);
    	m = rd();
    	register int s = 0, x = 0;
    	register ll tot_a = 0, tot_b = 0;
    	while (m--) {
    		tot_a = tot_b = 0;
    		s = rd(); x = rd();
    		for (int i = lg; i >= 0; --i) {
    			if (!f[s][i][1] || (tot_a + tot_b + d[s][i][1].fir + d[s][i][1].sec > x)) continue;
    			tot_b += d[s][i][1].fir;
    			tot_a += d[s][i][1].sec;
    			s = f[s][i][1];
    		}
    		printf("%lld %lld
    ", tot_a, tot_b);
    	}
    	return 0;
    }
  • 相关阅读:
    kebernet--新手填坑
    CentOS7下yum安装Kubernetes
    Centos 7 下部署Django + uWSGI + Nginx
    IPV4地址学习笔记
    【转】性能测试报告模板 V1.0
    【转载】Nginx简介及使用Nginx实现负载均衡的原理
    分布下 session 共享同步
    GC 收集算法及几种收集器优缺点讲解
    单线程集合和多线程集合
    在linux中实现多网卡的绑定 介绍常见的7种Bond模式
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9868559.html
Copyright © 2011-2022 走看看