YbtOJ#493-最大分数【斜率优化dp,分治】
正題
題目鏈接:http://172.17.55.160/contest/117/problem/1
題目大意
nnn個數的一個序列,給其中的一些數打上標記。
一個標記方案的貢獻為s1s_1s1?表示有多少對L,RL,RL,R滿足區間[L,R][L,R][L,R]都被打上了標記,s2s_2s2?表示標記的數字和。貢獻為s1?s2s_1-s_2s1??s2?
mmm次詢問,修改一個數后,求最大的可能貢獻(詢問之間相互獨立)
1≤n,m≤3×1051\leq n,m\leq 3\times 10^51≤n,m≤3×105
解題思路
先把答案減去一個∑i=1nai\sum_{i=1}^na_i∑i=1n?ai?,這樣就變為對于一段[L,R][L,R][L,R]要么選擇s1s_1s1?要么選擇s2s_2s2?
先考慮不帶修改怎么搞,設fif_ifi?表示前iii個的最大貢獻。
定義si=∑j=1iais_i=\sum_{j=1}^ia_isi?=∑j=1i?ai?然后有方程
fi=max{fj+max{si?sj,(i?j2)}}f_i=max\{f_j+max\{s_i-s_j,\binom{i-j}{2}\}\}fi?=max{fj?+max{si??sj?,(2i?j?)}}
這個東西可以斜率優化搞(考場上犯病寫了個CDQCDQCDQ,調了我半天)
然后帶修改,考慮到每次只會影響一個數字,可以理解為一個前綴和后綴拼起來。把剛剛那個dpdpdp再反過來做一次記為gig_igi?。
那么現在對于修改的位置xxx,我們要么選擇xxx,要么跨過xxx,也就是最大化
max{fj+gi+si?1?sj,fj+gi+(i?j?12)}(i∈[0,x?1],j∈[x+1,n+1])max\{f_j+g_i+s_{i-1}-s_j,f_j+g_i+\binom{i-j-1}{2}\}(i\in[0,x-1],j\in[x+1,n+1])max{fj?+gi?+si?1??sj?,fj?+gi?+(2i?j?1?)}(i∈[0,x?1],j∈[x+1,n+1])
前面那個可以把兩個前/后綴的max的fj?sjf_j-s_jfj??sj?和gi+si?1g_i+s_{i-1}gi?+si?1?加起來就好了。
后面那個考慮分治,我們每次分治到一個位置[l,mid,r][l,mid,r][l,mid,r],如果需要往左走就統計i∈[0,l?1]i\in[0,l-1]i∈[0,l?1]和j∈[mid+1,r]j\in[mid+1,r]j∈[mid+1,r]的答案。右邊同理。
因為我們的每次的時間復雜度是外面的大小,所以我們可以維護一個前后綴的凸殼,然后在上面二分時間復雜度就是O(nlog?2n)O(n\log^2 n)O(nlog2n)的。
同時維護兩個凸殼需要回溯所以很麻煩,分開兩次正反做一次就好了。
時間復雜度O(nlog?2n)O(n\log^2 n)O(nlog2n)
code
(考場代碼,有點丑)
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define ll long long using namespace std; const ll N=3e5+10,inf=1e18; ll n,m,ans,lmax,rmax,top,st[N],suf[N]; ll a[N],f[N],g[N],s[N],prt[N],w[N],yf[N]; vector<ll > q[N]; ll px(ll x,ll *f) {return f[x]*2+x*x-x;} ll xj(ll x1,ll y1,ll x2,ll y2) {return x1*y2-x2*y1;} ll xl(ll a,ll b,ll c,ll *f){ll y1=px(b,f)-px(a,f),x1=b-a;ll y2=px(c,f)-px(a,f),x2=c-a;return xj(x1,y1,x2,y2); } ll ck(ll l,ll r,ll *f) {return f[l]+(r-l+1)*(r-l)/2;} ll solve(ll l,ll r,ll *f){if(l==r)return f[l]-s[l];ll mid=(l+r)>>1;ll maxs=solve(l,mid,f);top=0;for(ll i=l;i<=mid;i++){while(top>1&&xl(st[top-1],st[top],i,f)>=0)top--;st[++top]=i;}for(ll i=mid+1;i<=r;i++){while(top>1&&ck(st[top],i,f)<ck(st[top-1],i,f))top--;f[i]=max(f[i],max(ck(st[top],i,f),s[i]+maxs));}maxs=max(maxs,solve(mid+1,r,f));return maxs; } ll cw(ll l,ll r) {return f[l]+g[r]+(r-l-1)*(r-l)/2;} ll xll(ll a,ll b,ll c){ll y1=(yf[b]-yf[a])*2,x1=b-a;ll y2=(yf[c]-yf[a])*2,x2=c-a;return xj(x1,y1,x2,y2); } ll xlr(ll a,ll b,ll c){ll y1=yf[b]-yf[a],x1=(n-b+1)-(n-a+1);ll y2=yf[c]-yf[a],x2=(n-c+1)-(n-a+1);return xj(x1,y1,x2,y2); } void calc(ll L,ll R){if(L==R){for(ll i=0;i<q[L].size();i++){ll x=q[L][i],tmp;prt[x]=max(ans-w[x]+a[L]-s[n],prt[x]);}while(top>1&&xll(st[top-1],st[top],L)>=0)top--;st[++top]=L;return;}ll mid=(L+R)>>1,pa=ans;if(top){for(ll i=mid+1;i<=R;i++){ll l=1,r=top-1;while(l<=r){ll x=(l+r)>>1;if(cw(st[x],i)<=cw(st[x+1],i))l=x+1;else r=x-1;}ans=max(ans,cw(st[l],i));}}calc(L,mid);ans=pa;calc(mid+1,R);return; } void cblc(ll L,ll R){if(L==R){for(ll i=0;i<q[L].size();i++){ll x=q[L][i],tmp;prt[x]=max(ans-w[x]+a[L]-s[n],prt[x]);}while(top>1&&xlr(st[top-1],st[top],L)>=0)top--;st[++top]=L;return;}ll mid=(L+R)>>1,pa=ans;if(top){for(ll i=L;i<=mid;i++){ll l=1,r=top-1;while(l<=r){ll x=(l+r)>>1;if(cw(i,st[x])<=cw(i,st[x+1]))l=x+1;else r=x-1;}ans=max(ans,cw(i,st[l]));}}cblc(mid+1,R);ans=pa;cblc(L,mid);return; } signed main() {freopen("score.in","r",stdin);freopen("score.out","w",stdout);scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld",&a[n-i+1]);for(ll i=1;i<=n;i++)s[i]=s[i-1]+a[i];solve(0,n,g);for(ll i=1;i<n-i+1;i++)swap(a[i],a[n-i+1]),swap(g[i],g[n-i+1]);for(ll i=1;i<=n;i++)s[i]=s[i-1]+a[i];solve(0,n,f);scanf("%lld",&m);for(ll i=1;i<=m;i++){ll x;scanf("%lld%lld",&x,&w[i]);q[x].push_back(i);}suf[n+2]=-inf;for(ll i=n+1;i>=1;i--)suf[i]=max(suf[i+1],g[i]+s[i-1]);for(ll i=0,pre=-inf;i<=n;i++){for(ll j=0;j<q[i].size();j++){ll x=q[i][j];prt[x]=suf[i+1]+pre-s[n];}pre=max(pre,f[i]-s[i]);}ans=-inf;top=0;for(ll i=1;i<=n;i++)yf[i]=f[i]*2+i*i+i;calc(0,n+1);ans=-inf;top=0;for(ll i=1;i<=n;i++)yf[i]=g[i]*2+(n-i+1)*(n-i+1)+(n-i+1);cblc(0,n+1);for(ll i=1;i<=m;i++)printf("%lld\n",max(prt[i],0ll));return 0; }總結
以上是生活随笔為你收集整理的YbtOJ#493-最大分数【斜率优化dp,分治】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Imagination 联合 Venta
- 下一篇: YbtOJ-大收藏家【分层图,最大流】