[ARC063] F - すぬけ君の塗り絵 2 / Snuke's Coloring 2 单调栈+线段树

首先发现一定能找到一个最优解使得矩形的每条边要么是边界,要么有一个关键点,所以转化为求周长最大的内部不存在关键点的矩形。
不难发现选择一竖条或者一横条是一定合法的,那么答案下界就至少是 2(max(h,w)+1) 2 ( max ( h , w ) + 1 ) ,那么最优解一定过 x=w2 x = w 2 或者 y=h2 y = h 2 ,因为在某个四分之一矩形内部是不可能达到答案下界的。
先考虑经过 x=w2 x = w 2 的答案(另一部分同理),那么枚举上边界 yL y L ,用两个单调栈维护下边界 yR y R 递增时的左右边界 xL,xR x L , x R ,可以 O(n2) O ( n 2 ) 求解。其实对于 yR y R 递增的过程,我们可以用线段树维护 yL=1..n y L = 1.. n 的最小周长,单调栈的操作相当于在线段树上区间加减,然后维护一个全局最小值即可。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define chkmin(a,b) a=min(a,b)
#define chkmax(a,b) a=max(a,b)
#define mid (l+r>>1)
#define N 200010
using namespace std;
int w,h,n,m,z[N],hl[N],hr[N],ans,topl,topr;
int read()
{
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    return x*f;
}
struct pt
{
    int x,y;
}a[N],sl[N],sr[N];
struct tree
{
    int add,mx;
    tree *ls,*rs;
    tree(){ls=rs=0;mx=add=0;}
    void update()
    {
        mx=max(ls->mx,rs->mx);
    }
    void cal(int d)
    {
        mx+=d;add+=d;
    }
    void pushdown()
    {
        ls->cal(add);rs->cal(add);
        add=0;  
    }
    void build(int l,int r)
    {
        if(l==r) return ;
        (ls=new tree)->build(l,mid);
        (rs=new tree)->build(mid+1,r);
    }
    void mdf(int l,int r,int lx,int rx,int d)
    {
        if(lx>rx||d==0) return ;
        if(l==lx&&r==rx) {cal(d);return ;}
        pushdown();
        if(rx<=mid) ls->mdf(l,mid,lx,rx,d);
        else if(lx>mid) rs->mdf(mid+1,r,lx,rx,d);
        else ls->mdf(l,mid,lx,mid,d),rs->mdf(mid+1,r,mid+1,rx,d);
        update();
    }
}*xtr;
void work()
{
    for(int i=1;i<=n;i++)
        z[i]=a[i].y;
    sort(z,z+n+1);z[n+1]=h;
    m=unique(z,z+n+2)-z-1;
    for(int i=1;i<=n;i++)
        a[i].y=lower_bound(z,z+m+1,a[i].y)-z;
    (xtr=new tree)->build(0,m); 
    for(int i=0;i<=m;i++)
        hl[i]=0,hr[i]=w;    
    for(int i=1;i<=n;i++)
        if(a[i].x<=(w>>1)) chkmax(hl[a[i].y],a[i].x);
        else chkmin(hr[a[i].y],a[i].x);         
    topl=topr=0;
    xtr->mdf(0,m,0,m,w);
    for(int i=1;i<=m;i++)
    {
        xtr->mdf(0,m,0,i-1,z[i]-z[i-1]);
        chkmax(ans,xtr->mx);
        for(;topl&&hl[i]>=sl[topl].x;topl--)
            xtr->mdf(0,m,sl[topl-1].y,sl[topl].y-1,sl[topl].x-hl[i]);   
        for(;topr&&hr[i]<=sr[topr].x;topr--)
            xtr->mdf(0,m,sr[topr-1].y,sr[topr].y-1,hr[i]-sr[topr].x);
        xtr->mdf(0,m,i-1,i-1,hr[i]-hl[i]-w);
        sl[++topl]=(pt){hl[i],i};sr[++topr]=(pt){hr[i],i};

    }   
}
int main()
{
    w=read();h=read();n=read();
    for(int i=1;i<=n;i++)
        a[i].x=read(),a[i].y=read();
    work();
    for(int i=1;i<=n;i++)
        a[i].y=z[a[i].y];
    swap(w,h);
    for(int i=1;i<=n;i++)
        swap(a[i].x,a[i].y);    
    work();
    printf("%d",ans<<1);            
    return 0;
}
Sure! Here's the C++ code that calculates the first day on which Takahashi has to take K pills or less: ```cpp #include <iostream> #include <vector> int main() { int N, K; std::cin >> N >> K; std::vector<int> a(N); std::vector<int> b(N); for (int i = 0; i < N; i++) { std::cin >> a[i] >> b[i]; } long long day = 1; long long remainingPills = 0; for (int i = 0; i < N; i++) { remainingPills += a[i]; if (remainingPills >= K) { std::cout << day << std::endl; return 0; } day++; remainingPills -= b[i]; if (remainingPills <= 0) { remainingPills = 0; } } day += (remainingPills + K - 1) / K; std::cout << day << std::endl; return 0; } ``` In this code, we first take the inputs N and K, representing the number of medicine types and the maximum number of pills Takahashi can take in a day. Then we take the arrays `a` and `b`, where `a[i]` represents the number of days Takahashi has to take `b[i]` pills of the `i-th` medicine. We iterate through the arrays and keep track of the remaining pills. If at any point the remaining pills are greater than or equal to K, we output the current day and exit the program. Otherwise, we increment the day counter, reduce the remaining pills by `b[i]`, and if the remaining pills become less than or equal to 0, we set it to 0. Finally, if there are still remaining pills, we calculate the additional days needed by dividing the remaining pills by K (rounded up) and add it to the current day. The result is the first day on which Takahashi has to take K pills or less. Please note that this code assumes valid inputs and does not include any error handling.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值