CF889E Mod Mod Mod
看到这题的第一眼想法:哇这不是从倒过来维护一些区间的右端点每次增加个区间,平移若干区间,得到个取值点,然后对于每个点二分出第一个能模的位置,暴力做得到的优秀复杂度吗?
哎等下,这东西好像要写个平衡树写个st表有点难写的亚子?
然后你发现他们写的都是不到1k的东西,因此肯定不用这么麻烦。
我们考虑正着维护,到了第个数模完之后,考虑维护一整段的答案,如果当前的是,则每个点拥有共同的初始值与斜率,点则是他们自己。那么一定是取最优。
然后这时候,则模完之后有效的是两段:与,新拆出来的段的初始值只需要加上询问点变化的差即可。容易发现这样每个数会模次,用map存状态,总复杂度。
code:
#include<bits/stdc++.h>
#define I inline
#define ll long long
#define db double
#define lb long db
#define N (200000+5)
#define M ((N<<1)+5)
#define K (700+5)
#define mod 1000000007
#define Mod (mod-1)
#define eps (1e-5)
#define ull unsigned ll
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((k+1)*(x)+(y))
#define R(n) (1ll*rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using namespace std;const ll INF=1e18;map<ll,ll> f;
int n,m,k;ll x,ToT;
int main(){
freopen("1.in","r",stdin);
int i,j;scanf("%d%lld",&n,&x);f[x-1]=0;for(i=2;i<=n;i++){
scanf("%lld",&x);ll Ts=-1e18;while(!f.empty()){
auto j=*--f.end();if(j.first<x){Ts>=0&&(f[x-1]=max(f[x-1],Ts));break;}Ts=max(j.second+(i-1)*(j.first/x*x-x),Ts);
f[j.first%x]=max(f[j.first%x],j.second+(j.first-j.first%x)*(i-1));f.erase(--f.end());
}
} for(auto i:f) ToT=max(ToT,i.second+i.first*n);printf("%lld\n",ToT);
}
分类:
CodeForces
标签:
dp
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2021-08-06 luogu P4827 [国家集训队] Crash 的文明世界
2021-08-06 luogu P4284 [SHOI2014]概率充电器