• 【CodeVS 1199】【NOIP 2012】开车旅行


    http://codevs.cn/problem/1199/

    主要思想是倍增,对于第一个回答从后往前扫,依次插入平衡树中。

    我写的splay,比较繁琐。

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N = 100003;
    int in() {
    	int k = 0, fh = 1; char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar())
    		if (c == '-') fh = -1;
    	for(; c >= '0' && c <= '9'; c = getchar())
    		k = (k << 3) + (k << 1) + c - '0';
    	return k * fh;
    }
    
    int h[N], n, m, nxt_a[N], nxt_b[N], f[N][18], sum_a[N][18], sum_b[N][18];
    
    struct Splay {
    	struct node {
    		node *ch[2], *fa;
    		int id, num;
    		bool pl() {return fa->ch[1] == this;}
    		void setc(node *r, bool c) {ch[c] = r; r->fa = this;}
    	} *root, *null;
    	void init() {
    		null = new node;
    		null->id = null->num = 0;
    		null->ch[0] = null->ch[1] = null->fa = null;
    		root = null;
    	}
    	void printall(node *r) {
    		if (r == null) return;
    		printall(r->ch[0]);
    		printf("%d ", r->num);
    		printall(r->ch[1]);
    	}
    	void rotate(node *r) {
    		node *f = r->fa;
    		bool c = r->pl();
    		if (f != root) f->fa->setc(r, f->pl());
    		else root = r, r->fa = null;
    		f->setc(r->ch[!c], c);
    		r->setc(f, !c);
    	}
    	void splay(node *r) {
    		for(; r->fa != null; rotate(r))
    			if (r->fa->fa != null) rotate(r->fa->pl() == r->pl() ? r->fa : r);
    	}
    	struct data {
    		int del, h, id;
    		bool operator < (const data &A) const {
    			return (del == A.del ? h < A.h : del < A.del);
    		}
    	} a[5];
    	node *getl(int num, int to) {
    		node *r = root->ch[0];
    		if (r == null) {a[to] = (data) {0x7fffffff, 0, 0}; return r;}
    		while (r->ch[1] != null) r = r->ch[1];
    		a[to] = (data) {abs(num - r->num), r->num, r->id};
    		return r;
    	}
    	node *getr(int num, int to) {
    		node *r = root->ch[1];
    		if (r == null) {a[to] = (data) {0x7fffffff, 0, 0}; return r;}
    		while (r->ch[0] != null) r = r->ch[0];
    		a[to] = (data) {abs(num - r->num), r->num, r->id};
    		return r;
    	}
    	void mk_nxt(int &back_1, int &back_2, int id, int num) {
    		node *r = root;
    		if (r == null) {
    			root = new node;
    			root->id = id; root->num = num;
    			root->ch[0] = root->ch[1] = root->fa = null;
    			back_1 = back_2 = 0;
    			return;
    		}
    		bool c;
    		while (true) {
    			if (r->num > num) c = 0;
    			else c = 1;
    			if (r->ch[c] == null) {
    				r->ch[c] = new node;
    				r->ch[c]->fa = r;
    				r = r->ch[c];
    				r->id = id; r->num = num;
    				r->ch[0] = r->ch[1] = null;
    				splay(r);
    				node *ll = getl(num, 0), *rr = getr(num, 1);
    				if (ll != null) {splay(ll); getl(num, 2);} else a[2] = (data) {0x7fffffff, 0, 0};
    				if (rr != null) {splay(rr); getr(num, 3);} else a[3] = (data) {0x7fffffff, 0, 0};
    				sort(a, a + 4);
    				if (a[1].id != 0) {
    					back_1 = a[1].id; back_2 = a[0].id;
    				} else if (a[0].id != 0) {
    					back_1 = 0; back_2 = a[0].id;
    				} else {
    					back_1 = 0; back_2 = 0;
    				}
    				return;
    			} else r = r->ch[c];
    		}
    	}
    } T;
    
    void cal(int &a, int &b, int s, int x) {
    	a = b = 0;
    	for(int i = 17; i >= 0; --i)
    		if (f[s][i] && sum_a[s][i] + sum_b[s][i] <= x) {
    			a += sum_a[s][i]; b += sum_b[s][i];
    			x -= sum_a[s][i]; x -= sum_b[s][i];
    			s = f[s][i];
    		}
    	if (sum_a[s][0] <= x && nxt_a[s])
    		a += sum_a[s][0];
    }
    
    int main() {
    	T.init();
    	n = in();
    	for(int i = 1; i <= n; ++i) h[i] = in();
    	for(int i = n; i >= 1; --i)	T.mk_nxt(nxt_a[i], nxt_b[i], i, h[i]);
    	
    	for(int i = 1; i <= n; ++i) {
    		if (nxt_a[i]) sum_a[i][0] = abs(h[nxt_a[i]] - h[i]);
    		if (nxt_b[nxt_a[i]]) {
    			sum_b[i][0] = abs(h[nxt_b[nxt_a[i]]] - h[nxt_a[i]]);
    			f[i][0] = nxt_b[nxt_a[i]];
    		}
    	}
    	for(int j = 1; j <= 17; ++j)
    		for(int i = 1; i <= n; ++i)
    			if (f[f[i][j - 1]][j - 1]) {
    				f[i][j] = f[f[i][j - 1]][j - 1];
    				sum_a[i][j] = sum_a[i][j - 1] + sum_a[f[i][j - 1]][j - 1];
    				sum_b[i][j] = sum_b[i][j - 1] + sum_b[f[i][j - 1]][j - 1];
    			}
    	
    	int a, b, s, x, ans = 0; double ans_num = -1.0, now;
    	x = in();
    	for(int i = 1; i <= n; ++i) {
    		cal(a, b, i, x);
    		if (b != 0) now = 1.0 * a / b;
    		else now = -1.0;
    		if (ans_num == -1.0 || (ans_num != -1.0 && now != -1.0 && now <= ans_num))
    			if (fabs(ans_num - now) < 1e-12) {
    				if (h[i] > h[ans]) ans = i;
    			} else ans_num = now, ans = i;
    	}
    	printf("%d
    ", ans);
    	
    	m = in(); int i = 0;
    	while (m--) {
    		++i;
    		s = in(); x = in();
    		cal(a, b, s, x);
    		printf("%d %d
    ", a, b);
    	}
    	
    	return 0;
    }
    

    _(:з」∠)_

  • 相关阅读:
    软工实践
    福大软工 · 最终作业
    福大软工 · 第十二次作业
    Beta冲刺(7/7)
    Beta冲刺(5/7)
    Beta 冲刺(6/7)
    Beta冲刺 (4/7)
    Beta冲刺 (3/7)
    Beta冲刺 (2/7)
    Beta 冲刺(1/7)
  • 原文地址:https://www.cnblogs.com/abclzr/p/5859446.html
Copyright © 2020-2023  润新知