首页 > 其他分享 >D. Slimes

D. Slimes

时间:2024-02-28 17:56:35浏览次数:20  
标签:sufch -- ll Slimes mid 区间 粘液

原题链接

题解

对于任何一个粘液块s而言,要么是从左边被吞并,要么是从右边被吞并,根据对称性,两边的决策是一样的,因此先考虑右边

对于被右边吞并而言,有以下几个特征
1.起始粘液一定是吞掉了s右边一整块连续的粘液
2.右边区间一定存在大小不同的相邻粘液,这样才能发动吞并
3.由一二猜想,只要存在不同的相邻粘液,这一片区间上的粘液都会被吞并至只剩下一个粘液
证明:
假如只存在一个不同相邻粘液
最大的吞并比他小的-->原来大的比同伴大-->吞并同伴
存在两个及以上同理
4.因此我猜想,对于右边区间而言,存在不同相邻粘液块且区间和大于s的最小区间就是答案
开始证明
运用反证法:如果该区间不是最小区间,那么区间缩小,区间和会减小以至于可能小于s,也可能不存在相同相邻粘液,与题意不符,得证

然后很容易发现区间和具有单调性,是否存在不同相邻粘液也有单调性(不会减小)

因此二分

code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll pres[300005]={0};
ll sufs[300005]={0};
ll a[300005]={0};
ll prech[300005]={0};
ll sufch[300005]={0};
ll press(ll l,ll r,ll x)
{
    r++;
    l--;
    ll i=l;
    if(a[i]<a[i+1])return i+1;
    while(l+1<r)
    {
        ll mid=(l+r)/2;
        if(pres[mid]-pres[i]>a[i]&&prech[mid]-prech[i+1]>0)
            r=mid;
        else l=mid;
    }
    return r;
}

ll sufss(ll l,ll r,ll x)
{
    l--;
    r++;
    ll i=r;
    if(a[i-1]>a[i])return i-1;
    while(l+1<r)
    {
        ll mid=(l+r)/2;
        if(sufs[mid]-sufs[i]>a[i]&&sufch[mid]-sufch[i-1]>0)
            l=mid;
        else r=mid;
    }
    return l;
}
int main()
{
    ll t;
    cin>>t;
    while(t--)
    {
        ll n;
        cin>>n;
        for(ll i=1;i<=n;i++)
        {
            cin>>a[i];
            pres[i]=pres[i-1]+a[i];
            if(i!=1)prech[i]=prech[i-1]+(a[i]!=a[i-1]);
        }

        sufs[n]=a[n];
        sufch[n]=0;
        for(ll i=n-1;i>=1;i--)
        {
            sufs[i]=sufs[i+1]+a[i];
            sufch[i]=sufch[i+1]+(a[i]!=a[i+1]);
        }

        for(ll i=1;i<=n;i++)
        {
            if(i==1)
            {
                ll r=press(2,n,a[1]);
                if(r!=n+1) cout<<r-i<<" ";
                else printf("-1 ");
            }
            else if(i==n)
            {
                ll l=sufss(1,n-1,a[1]);
                if(l!=0) cout<<i-l<<" ";
                else printf("-1 ");
            }
            else
            {
                ll r=press(i+1,n,a[i]);
                ll l=sufss(1,i-1,a[i]);
                if(l!=0&&r!=n+1)cout<<min(i-l,r-i)<<" ";
                else if(l!=0) cout<<i-l<<" ";
                else if(r!=n+1) cout<<r-i<<" ";
                else printf("-1 ");
            }
        }

        puts("");
    }
    return 0;
}

标签:sufch,--,ll,Slimes,mid,区间,粘液
From: https://www.cnblogs.com/pure4knowledge/p/18041273

相关文章

  • AGC004B Colorful Slimes
    ${\scr\color{Orchid}{\text{生于尘埃,溺于人海,死于理想高台。}}}$题目链接:ColorfulSlimes${\scr\color{Cyan}{\text{Solution}}}$分析思路:挺神奇的$dp$一个比较显然的结论:最小值的方案中第$2$种操作最多用$n-1$次证明大概就是一个数用$n-1$次一定会变成另一个数......
  • [ABC140F] Many Slimes
    2023-02-13题目题目传送门翻译翻译难度&重要性(1~10):6题目来源AtCoder题目算法贪心解题思路用了两个multiseta和一个sets,一个multiset用来记录用来存还剩哪些数没生成,另一个用来存已经生成了哪些数,然后后面放数的时候就枚举第二个multiset来生成新的数。然......
  • 【luogu CF618G】Combining Slimes(矩阵乘法)(DP)
    CombiningSlimes题目链接:luoguCF618G题目大意有一个长度为n的栈,如果栈顶两个值都是x就会合并成x+1,一开始没有东西。你有p的概率放进去一个1,1-p的概率放入2......