zoukankan      html  css  js  c++  java
  • ZOJ 3937 More Health Points (2016 浙江省赛 B题,可持久维护凸壳)

    题目链接  2016 ZJCPC Problem B

    题意  CF 660F的树上版本。

    其他做的方法都差不多,关键是把凸壳放到树上。

    每次确定扔掉几个元素的时候直接$O(1)$修改(先不清楚这个位置之后的元素因为之后还要恢复),然后$O(1)$恢复,通过这个来实现可持久。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define MP		make_pair
    #define fi		first
    #define se		second
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    
    int T;
    int n;
    int r;
    int deep[N], q[N];
    LL a[N], c[N], s[N];
    LL ans;
    vector <int> v[N];
    
    inline LL y(int x){
    	return c[x] - 1ll * deep[x] * s[x];
    }
    
    inline long double g(int j, int k){
    	double dy = 1.00 * y(j) - 1.00 * y(k);
    	double dx = 1.00 *  deep[j] - 1.00 * deep[k];
    	return dy / dx;
    }
    
    inline LL calc(int x, int y){
    	return c[x] - c[y] - 1ll * deep[y] * (s[x] - s[y]);
    }
    
    
    void pre(int x, int fa, int dep){
    	deep[x] = dep;
    	s[x] = s[fa] + a[x];
    	c[x] = c[fa] + 1ll * dep * a[x];
    
    	for (auto u : v[x]){
    		pre(u, x, dep + 1);
    	}
    }
    
    inline int pos(LL x, int tail){
    	x = -x;
    	int l = 1, r = tail - 1, ret = 0;
    
    	while (l <= r){
    		int mid = (l + r) >> 1;
    		if (g(q[mid], q[mid - 1]) < x) l = (ret = mid) + 1;
    		else r = mid - 1;
    	}
    
    	return q[ret];
    }
    
    inline int gettail(int x, int tail){
    	int l = 2, r = tail, ret = 0;
    
    	if (g(x, q[1]) < g(q[1], q[0])) return 1;
    
    	while (l <= r){
    		int mid = (l + r) >> 1;
    		if (g(x, q[mid - 1]) >= g(q[mid - 1], q[mid - 2])) l = (ret = mid) + 1;
    		else r = mid - 1;
    	}
    
    	return ret;
    }
    
    void dfs(int x, int tail){
    
    	int y = pos(s[x], tail);
    	ans = max(ans, calc(x, y));
    
    	int cnt, t, re, la;
    	if (tail <= 1 || g(x, q[tail - 1]) >= g(q[tail - 1], q[tail - 2])){
    		re = tail;
    		la = q[tail];
    		q[tail] = x;
    		tail++;
    		cnt = tail;
    	}	
    
    	else{
    		t = gettail(x, tail);    //get the position
    		re = t;
    		la = q[t];
    		q[t] = x;
    		cnt = t + 1;
    	}
    	//replace
    
    	for (auto u : v[x]) dfs(u, cnt);  //continue solving
    
    	q[re] = la;  //undo
    }		
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d", &n);
    		rep(i, 0, n + 1) v[i].clear();
    
    		rep(i, 1, n) scanf("%lld", a + i);
    		rep(i, 2, n){
    			int x;
    			scanf("%d", &x);
    			v[x].push_back(i);
    		}
    
    		pre(1, 0, 1);
    
    		rep(i, 0, n + 1) q[i] = 0;
    		r = 0;
    		q[r++] = 0;
    
    		ans = 0;
    		dfs(1, r);
    		printf("%lld
    ", ans);
    	}
    
    
    	return 0;
    }
    

      

  • 相关阅读:
    zhuan:Jmeter基础之---jmeter基础概念
    zhuan:JMeter基础之--元件的作用域与执行顺序
    zhuan:JMeter基础之—录制脚本
    zhuan:一种简单的数据库性能测试方法
    转:使用JMeter创建FTP测试计划
    转:JMeter基础之一 一个简单的性能测试
    性能学习
    [转]JMeter学习(一)工具简单介绍
    后端文件接收resd()和chunk的区别
    PyQt环境安装
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8961729.html
Copyright © 2011-2022 走看看