codeforce 889 E

题链

非常native的题目,我们考虑以下一些性质:

 .一个数若mo了一个小于自己的模数,那么其至少变成原来的一半。

 我们构造三元对(i,j,k)表示当前做到i位,当前x可以取0至j,当前的答案是k+i*j,

我们考虑这样的转移:

(i,j,k)to (i+1,j%num[i+1],k+i*(j-j%num[i+1]))

(i,j,k) to (i+1,num[i+1]-1,k+i*(j-j%num[i+1]-num[i+1])),

我们考虑dp:f[i][j]中计录max k,那么就有O(N^2)个状态,

我们发现比其小的状态转移后k可以最后统计,那么我们只要修改比其大的即可。

由前文性质得每个数最多log次修改,我们用map维护即可。

下文代码在C++11及更高环境下才能通过(auto 是C++11的保留字&&C++17除外,这玩意超级玄学)

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
using namespace std;
map<LL,LL> mp;
LL ans,A,B,nex;
LL n,a[1000007];
int main () {
    scanf("%lld",&n);
    for (int i=1;i<=n;i++) scanf("%lld",a+i);
    mp[(LL)a[1]-1]=0;
    for (int i=1;i<=n;i++) {
        while (1) {
            auto it=mp.lower_bound(a[i]);
            if (it==mp.end()||it->fi<a[i]) break;
            A=it->fi,B=it->se; mp.erase(it);
            nex=A%a[i];
            mp[nex]=max(mp[nex],B+(i-1)*(A-A%a[i]));
            mp[a[i]-1]=max(mp[a[i]-1],B+(i-1)*(A-A%a[i]-a[i]));
        }
    }
    for (auto i:mp)  ans=max(ans,i.fi*n+i.se);
    printf("%lld\n",ans);
} 

 

转载于:https://www.cnblogs.com/rrsb/p/8371104.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值