CF1710B Rain

\(\mathcal Link\)

首先,只需要考虑降雨中心即可。
证明:所有函数在两个相邻中心之间是下凸的,所以和也是下凸的,所以中间小于两端。

用二维差分容易求出各点的降雨量。

对于一个高度大于 \(m\) 的节点 \(i\),若 \(x\) 合法则 \(p_x-|i-x|\geq h_i-m\),即 \(p_x\geq h_i-m+\max(i-x,x-i)\),只需要维护两条直线上方部分的并即可,相当于截距 \(\max\)

#include <cstdio>
#include <algorithm>
#include <cctype>
#include <map>

using namespace std;

char buf[1<<14], *p1=buf, *p2=buf;
#define GetC() ((p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++)
struct Ios{}io;
template <typename _tp>
Ios &operator >>(Ios &in, _tp &x){
    x=0; int w=0; char c=GetC();
    for(;!isdigit(c);w|=c=='-', c=GetC());
    for(;isdigit(c);x=x*10+(c^'0'), c=GetC());
    if(w) x=-x;
    return in;
}

using ll=long long;

const int N=2e5+5;
const ll inf=1e18;

ll x[N], p[N];
map<ll, ll> d;


int main(){
    int T; io>>T;
    while(T--){
        d.clear();
        int n, m; io>>n>>m;
        for(int i=1;i<=n;++i){
            io>>x[i]>>p[i];
            ++d[x[i]-p[i]+1]; d[x[i]+1]-=2; ++d[x[i]+p[i]+1];
        }
        ll b=0, k=0, lst=-inf;
        ll b1=-inf, b2=-inf;
        for(auto cur:d){
            b+=k*(cur.first-lst);
            k+=cur.second;

            if(b>m){
                b1=max(b1, b-m-cur.first+1);
                b2=max(b2, b-m+cur.first-1);
            }
            lst=cur.first;
        }
        for(int i=1;i<=n;++i)
            printf("%d", (p[i]>=x[i]+b1)&&(p[i]>=b2-x[i]));
        puts("");
    }

    return 0;
}
posted @ 2023-02-23 10:45  pref_ctrl27  阅读(27)  评论(0编辑  收藏  举报