日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

YbtOJ#463-序列划分【二分答案,线段树,dp】

發(fā)布時(shí)間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 YbtOJ#463-序列划分【二分答案,线段树,dp】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

正題

題目鏈接:https://www.ybtoj.com.cn/problem/463


題目大意

給出長(zhǎng)度為nnn的序列A,BA,BA,B。要求劃分成若干段滿足

  • 對(duì)于任何i<ji<ji<j,若iiijjj不是同一段的,要求滿足Bi>AjB_i>A_jBi?>Aj?
  • 每一段AiA_iAi?的最大值的和不能超過(guò)mmm
  • 要求最小化每一段BiB_iBi?和的最大值。

    n∈[1,105],Ai,Bi∈[1,109],m∈[1,1012]n\in[1,10^5],A_i,B_i\in[1,10^9],m\in[1,10^{12}]n[1,105],Ai?,Bi?[1,109],m[1,1012]


    解題思路

    最大值最小化很顯然直接二分,然后變?yōu)榍竺恳欢?span id="ozvdkddzhkzd" class="katex--inline">AiA_iAi?最大值的和的最小值。

    第一個(gè)條件相當(dāng)于限制了什么位置能夠作為劃分段的末尾,求一個(gè)前綴min{bi}min\{b_i\}min{bi?}和一個(gè)后綴max{ai}max\{a_i\}max{ai?}能夠快速求出這些位置。

    然后考慮dpdpdp,轉(zhuǎn)移方程就是
    fi=min{fj+max{ak}(k∈(j,i])}f_i=min\{f_j+max\{a_k\}(\ k\in(j,i]\ )\}fi?=min{fj?+max{ak?}(?k(j,i]?)}

    二分的條件限制了jjj的范圍,加個(gè)指針就好了

    這個(gè)東西好像很難搞,但是注意到vj=max{ak}v_j=max\{a_k\}vj?=max{ak?}這一部分是遞減的,并且每次會(huì)讓所有viv_ivi?的一起和一個(gè)一起取maxmaxmax。

    因?yàn)槭沁f減的,所以每次加入一個(gè)新的就相當(dāng)于修改一段后綴的viv_ivi?,然后求一個(gè)區(qū)間的最大fi+vif_i+v_ifi?+vi?了。

    可以線段樹(shù)維護(hù),每個(gè)節(jié)點(diǎn)維護(hù)該區(qū)間最大的fi+vif_i+v_ifi?+vi?和最大的fif_ifi?。區(qū)間推平viv_ivi?的時(shí)候就可以拿最大的fif_ifi?來(lái)更新fi+vif_i+v_ifi?+vi?

    時(shí)間復(fù)雜度O(nlog?nlog?∑bi)O(n\log n\log\sum b_i)O(nlognlogbi?)


    code

    #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e5+10,inf=1e9+7; ll n,m,a[N],b[N],pre[N],suf[N],last[N]; ll lg[N],st[N][17],v[N<<2],w[N<<2],lazy[N<<2]; void Downdata(ll x){if(!lazy[x])return;lazy[x*2]=lazy[x*2+1]=lazy[x];w[x*2]=v[x*2]+lazy[x];w[x*2+1]=v[x*2+1]+lazy[x];lazy[x]=0;return; } void Changew(ll x,ll L,ll R,ll l,ll r,ll val){if(l>r)return;if(L==l&&R==r){w[x]=v[x]+val;lazy[x]=val;return;}ll mid=(L+R)>>1;Downdata(x);if(r<=mid)Changew(x*2,L,mid,l,r,val);else if(l>mid)Changew(x*2+1,mid+1,R,l,r,val);else Changew(x*2,L,mid,l,mid,val),Changew(x*2+1,mid+1,R,mid+1,r,val);w[x]=min(w[x*2],w[x*2+1]); } void Changev(ll x,ll l,ll r,ll pos,ll val){if(l==r){v[x]=val;w[x]=v[x]+lazy[x];return;}ll mid=(l+r)>>1;Downdata(x);if(pos<=mid)Changev(x*2,l,mid,pos,val);else Changev(x*2+1,mid+1,r,pos,val);w[x]=min(w[x*2],w[x*2+1]);v[x]=min(v[x*2],v[x*2+1]);return; } ll Ask(ll x,ll L,ll R,ll l,ll r){if(L==l&&R==r)return w[x];ll mid=(L+R)>>1;Downdata(x);if(r<=mid)return Ask(x*2,L,mid,l,r);if(l>mid)return Ask(x*2+1,mid+1,R,l,r);return min(Ask(x*2,L,mid,l,mid),Ask(x*2+1,mid+1,R,mid+1,r)); } ll RMQ(ll l,ll r){ll z=lg[r-l+1];return max(st[l][z],st[r-(1<<z)+1][z]); } bool check(ll x){memset(v,0x3f,sizeof(v));memset(w,0x3f,sizeof(w));memset(lazy,0,sizeof(lazy));ll sum=0,l=0,tmp=v[0];Changev(1,0,n,0,0);for(ll i=1;i<=n;i++){sum+=b[i];while(sum>x)l++,sum-=b[l];Changew(1,0,n,last[i],i-1,a[i]);if(pre[i]<=suf[i+1])continue;tmp=Ask(1,0,n,l,i);Changev(1,0,n,i,tmp);}return (tmp<=m); } signed main() {freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);scanf("%lld%lld",&n,&m);ll l=1,r=0;pre[0]=inf;for(ll i=1;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]),r+=b[i],l=max(l,b[i]),st[i][0]=a[i];for(ll i=2;i<=n;i++)lg[i]=lg[i>>1]+1;for(ll j=1;(1<<j)<=n;j++)for(ll i=1;i+(1<<j)-1<=n;i++)st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);for(ll i=1;i<=n;i++){ll l=1,r=i-1;while(l<=r){ll mid=(l+r)>>1;if(RMQ(mid,i)>a[i])l=mid+1;else r=mid-1;}last[i]=r;}for(ll i=1;i<=n;i++)pre[i]=min(pre[i-1],b[i]);for(ll i=n;i>=1;i--)suf[i]=max(suf[i+1],a[i]);while(l<=r){ll mid=(l+r)>>1;if(check(mid))r=mid-1;else l=mid+1;}check(l+1);printf("%lld\n",l); } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的YbtOJ#463-序列划分【二分答案,线段树,dp】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。