zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    } 
  • 相关阅读:
    黄金连分数
    第39级台阶
    四、绘图可视化之Seaborn
    三、绘图和可视化之matplotlib
    二、pandas入门
    python_111_动态导入模块
    爬虫_python3_抓取猫眼电影top100
    爬虫_python3_urllib
    python_112_网络编程 Socket编程
    python_111_异常处理
  • 原文地址:https://www.cnblogs.com/rrsb/p/8371104.html
Copyright © 2011-2022 走看看