CF889E-Mod Mod Mod【dp】
正題
題目鏈接:https://www.luogu.com.cn/problem/CF889E
題目大意
給出一個長度為nnn的序列aaa,定義函數f(i,x)f(i,x)f(i,x)有
f(n,x)=xmodanf(n,x)=x\bmod a_nf(n,x)=xmodan?
f(i,x)=(xmodai)+f(xmodai)(i<n)f(i,x)=(x\bmod a_i)+f(x\bmod a_i)(i<n)f(i,x)=(xmodai?)+f(xmodai?)(i<n)
求最大的f(1,x)f(1,x)f(1,x)。
1≤n≤2×105,1≤ai≤10131\leq n\leq 2\times 10^5,1\leq a_i\leq 10^{13}1≤n≤2×105,1≤ai?≤1013
解題思路
考慮到最優解中我們肯定存在某次取模aia_iai?后得到的是ai?1a_i-1ai??1,不然全部加111肯定更優。那么同樣的每個前綴的最優答案都滿足如下性質。
拿第一次來距離,就是說[0,a1)[0,a_1)[0,a1?)中最優的是a1a_1a1?,由于答案遞減,那么還沒有減去的值(目前的xxx)可能影響到后面的狀態,那么我們考慮維護fi,jf_{i,j}fi,j?表示目前的x=jx=jx=j時已經被膜去的值貢獻為fi,jf_{i,j}fi,j?,也就是答案目前為i×j+fi,ji\times j+f_{i,j}i×j+fi,j?。
那么這個轉移來說我們就可以大膽地有fi,j=max{fi,k}(k≥j)f_{i,j}=max\{f_{i,k}\}(k\geq j)fi,j?=max{fi,k?}(k≥j)了,也就是開始時可以設fi,a1?1=1f_{i,a_1-1}=1fi,a1??1?=1,會發現這樣來轉移的話最多只有nnn個有用的值(前綴最大)。
轉移的時候統計上減少的值對前面的貢獻即可,用一個mapmapmap存下所有的有用位置和值進行轉移就好了,因為一個數字被模之后至少減少一半所以一個數字操作次數為log?ai\log a_ilogai?次。
時間復雜度:O(nlog?nlog?ai)O(n\log n\log a_i)O(nlognlogai?)
code
#include<cstdio> #include<cstring> #include<algorithm> #include<map> #define ll long long using namespace std; const ll N=2e5+10; ll n,ans;map<ll,ll> f; map<ll,ll>::iterator it; signed main() {scanf("%lld",&n);for(ll i=1,x;i<=n;i++){scanf("%lld",&x);if(i==1)f[x-1]=0;else{for(it=f.lower_bound(x);it!=f.end();f.erase(it++)){ll j=(*it).first,w=(*it).second;f[j%x]=max(f[j%x],w+(i-1)*(j-j%x));f[x-1]=max(f[x-1],w+(i-1)*((j+1)/x*x-x));}}}for(it=f.begin();it!=f.end();it++)ans=max(ans,(*it).first*n+(*it).second);printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的CF889E-Mod Mod Mod【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 普拉多和兰德酷路泽,教你如何选择?
- 下一篇: 耋耄怎么读 耋耄读音及释义