zoukankan      html  css  js  c++  java
  • LOJ #2392. 「JOISC 2017 Day 1」烟花棒(贪心)

    https://loj.ac/problem/2392

    第一步二分答案。

    注意其它人也是可以移动的,且其它人肯定往中间靠拢。

    考虑不可能两个人同时拿着烟花跑,一个人跑(这个人跑完后再用新的烟花跑是一样的)是更优的,所以遇到一个人相当于时间加T。

    问题变为:
    有两个队列,每个队列有一些数,你需要从左往右选数,满足当前的时间一直(ge 0),问是否可行。

    和这题类似:
    http://www.lydsy.com/JudgeOnline/problem.php?id=3709

    考虑如果选了一个负数,那么就要一直选直到和(ge 0),不然就不会选这个负数。

    把每个队列缩成若干((x,y)(yge 0)):进来前要(ge x),出去后加了(y),注意会剩下一些不能缩的。

    先看,能不能把二元组做完,对于剩下的,考虑先加上它们,再倒过来做,问题等价。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    const int N = 2e5 + 5;
    
    ll n, k, T;
    ll x[N];
    
    #define db double
    
    db a[N], b[N]; int a0, b0;
    db c[N], d[N]; int c0, d0;
    
    struct P {
    	db x, y;
    	P(db _x = 0, db _y = 0) {
    		x = _x, y = _y;
    	}
    };
    
    P p[N], q[N]; int p0, q0;
    
    void build(db *a, int &a0, db *c, int &c0) {
    	db s = 0; int la = 0;
    	fo(i, 1, a0) {
    		s += a[i];
    		if(s >= 0) s = 0, la = i;
    	}
    	fd(i, a0, la + 1) c[++ c0] = -a[i];
    	a0 = la;
    }
    
    void build(db *a, int &a0, P *p, int &p0) {
    	db s = 0, mx = 0;
    	fo(i, 1, a0) {
    		s += a[i];
    		mx = max(mx, -s);
    		if(s >= 0) {
    			p[++ p0] = P(mx, s);
    			s = 0, mx = 0;
    		}
    	}
    }
    
    int work(db &z, P *p, int &p0, P *q, int &q0) {
    	if(z < 0) return 0;
    	int l = 1, r = 1;
    	while(l <= p0 || r <= q0) {
    		if(l <= p0 && z >= p[l].x) {
    			z += p[l ++].y;
    			continue;
    		}
    		if(r <= q0 && z >= q[r].x) {
    			z += q[r ++].y;
    			continue;
    		}
    		return 0;
    	}
    	return 1;
    }
    
    int pd(ll mi) {
    	a0 = b0 = c0 = d0 = 0;
    	fd(i, k - 1, 1) {
    		a[++ a0] = (db) -(x[i + 1] - x[i]) / mi / 2;
    		a[++ a0] = T;
    	}
    	fo(i, k + 1, n) {
    		b[++ b0] = (db) -(x[i] - x[i - 1]) / mi / 2;
    		b[++ b0] = T;
    	}
    	
    	build(a, a0, c, c0);
    	build(b, b0, d, d0);
    	
    	p0 = q0 = 0;
    	build(a, a0, p, p0);
    	build(b, b0, q, q0);
    	
    	db z = T;
    	if(!work(z, p, p0, q, q0)) return 0;
    	
    	fo(i, 1, c0) z -= c[i];
    	fo(i, 1, d0) z -= d[i];
    	
    	p0 = q0 = 0;
    	
    	build(c, c0, p, p0);
    	build(d, d0, q, q0);
    	
    	return work(z, p, p0, q, q0);
    }
    
    int main() {
    	scanf("%lld %lld %lld", &n, &k, &T);
    	fo(i, 1, n) scanf("%lld", &x[i]);
    	if(x[1] == x[n]) {
    		pp("0
    "); return 0;
    	}
    	ll as = 0;
    	for(ll l = 1, r = 1e18; l <= r; ) {
    		ll m = l + r >> 1;
    		if(pd(m)) as = m, r = m - 1; else l = m + 1;
    	}
    	pp("%lld
    ", as);
    }
    
  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/coldchair/p/12968747.html
Copyright © 2011-2022 走看看