Codeforces 889E - Mod Mod Mod(dp+状态设计)
题目名称 hopping
我们记 \(x_i=X\bmod a_1\bmod a_2\bmod\dots\bmod a_i\),也就是 \(X\) 连续 mod 上前 \(i\) 个数后得到的结果。
一个非常 naive 的想法是设 \(dp_{i,j}\) 表示考虑到前 \(i\) 个数,当前的 \(x_i=j\) 的最大的 \(\sum\limits_{k=1}^ix_k\),显然有一个 \(\mathcal O(na_i)\) 的转移。但事实上稍微了解一下 \(dp\) 优化的同学都可用看出这个 \(dp\) 是没有前途的,因为这个状态本身就无法优化,每个 \(dp_{i,j}\) 都有可能对最终的 \(dp_n\) 产生贡献。
于是我们只好换个状态。首先可以观察到一个性质,就是若 \(x_i\ne 0\),那么若我们令 \(X\leftarrow X-1\) 一定有新的 \(x_i\) 等于原本的 \(x_i\) 减 \(1\),我们记 \(Y=\sum\limits_{j=1}^ix_j-x_i\),根据上面的推论可知,如果我们令 \(X\leftarrow X-x_i+v(v\in[0,x_i])\) 一定有 \(\sum\limits_{j=1}^ix_j=Y+vi\)。于是我们考虑将 \([0,j]\) 搞在一起转移。设 \(dp_{i,j}\) 为考虑到前 \(i\) 个数,当前的 \(x_i=j\) 的最大的 \(Y\)。考虑怎么转移,我们考虑枚举一个 \(k\) 并将 \(X\) 改为 \(X-x_i+k\),那么就有 \(dp_{i+1,k\bmod a_{i+1}}\leftarrow dp_{i,j}+(k-k\bmod a_{i+1})\times i\)(因为将 \(X\) 改为 \(X-x_i+k\) 之后,真实的 \(\sum\limits_{j=1}^ix_j=Y+ki\),\(\sum\limits_{j=1}^ix_j-(k\bmod a_{i+1})=Y+ki-i(k\bmod a_{i+1})=dp_{i,j}+(k-k\bmod a_{i+1})\times i\)),但显然我们不可能枚举 \(k\) 进行转移,考虑将 \([0,j]\) 中所有数 \(\bmod a_{i+1}\) 的值写成一排,若 \(j\ge a_{i+1}\) 那显然是若干个 \(0...a_{i+1}-1\) 的周期加一个零头,不难发现我们最优转移点只有两个,那就是最后一个周期的 \(a_{i+1}-1\),以及最后零头部分的最后一个数(\(j\bmod a_{i+1}\)),因为其他状态要么没有这两个状态来得优,要么可以通过这两个状态在未来的转移中得到,这个稍微想想就能想通;若 \(j<a_{i+1}\),与上面的情况也类似,只不过少了最后一个周期的 \(a_{i+1}-1\) 的情况。形式化地写下来就是以下状态转移方程:
\(a_{i+1,j}\leftarrow dp_{i,j}(j<a_{i+1})\)
\(a_{i+1,j\bmod a_{i+1}}\leftarrow dp_{i,j}+(j-j\bmod a_{i+1})\times i(j\ge a_{i+1})\)
\(a_{i+1,a_{i+1}-1}\leftarrow dp_{i+j}+(\lfloor\dfrac{j+1}{a_{i+1}}\rfloor\times a_{i+1}-a_{i+1})\times i(j\ge a_{i+1})\)
第一维可以直接去掉,第二维可以用 map 优化,注意到每个 \(j\) 最多转移 \(\log a_i\) 次,因此复杂度 \(n\log a_i\log n\),可通过此题。
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=2e5;
int n;ll a[MAXN+5];
map<ll,ll> dp;
int main(){
scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
dp[a[1]-1]=0;
for(int i=1;i<n;i++){
for(map<ll,ll>::iterator it=dp.lower_bound(a[i+1]);it!=dp.end();it++){
ll x=it->fi,y=it->se;
dp[x%a[i+1]]=max(dp[x%a[i+1]],y+1ll*i*(x-x%a[i+1]));
dp[a[i+1]-1]=max(dp[a[i+1]-1],y+1ll*i*((x+1)/a[i+1]*a[i+1]-a[i+1]));
} dp.erase(dp.lower_bound(a[i+1]),dp.end());
} ll ans=0;
for(map<ll,ll>::iterator it=dp.begin();it!=dp.end();it++){
ll x=it->fi,y=it->se;chkmax(ans,y+x*n);
} printf("%lld\n",ans);
return 0;
}
Codeforces 889E - Mod Mod Mod(dp+状态设计)的更多相关文章
- 1113: [视频]树形动态规划(TreeDP)8:树(tree)(树形dp状态设计总结)
根据最近做的几道树形dp题总结一下规律.(从这篇往前到洛谷 P1352 ) 这几道题都是在一颗树上,然后要让整棵树的节点或边 满足一种状态.然后点可以影响到相邻点的这种状态 然后求最小次数 那么要从两 ...
- 教主泡嫦娥[有趣的dp状态设计]
P1342 教主泡嫦娥 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 2012年12月21日下午3点14分35秒,全世界各国的总统以及领导人都已经汇聚在中国 ...
- Dp状态设计与方程总结
1.不完全状态记录<1>青蛙过河问题<2>利用区间dp 2.背包类问题<1> 0-1背包,经典问题<2>无限背包,经典问题<3>判定性背包问 ...
- Educational Codeforces Round 62 E 局部dp + 定义状态取消后效性
https://codeforces.com/contest/1140/problem/E 局部dp + 定义状态取消后效性 题意 给你一个某些位置可以改变的字符串,假如字符串存在回文子串,那么这个字 ...
- 关于一类容斥原理设计 dp 状态的探讨
写在前面 为什么要写?因为自己学不明白希望日后能掌握. 大体思路大概是 设计一个容斥的方案,并使其贡献可以便于计算. 得出 dp 状态,然后优化以得出答案. 下列所有类似 \([l,r]\) 这样的都 ...
- codeforces 55D - Beautiful numbers(数位DP+离散化)
D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- codeforces 691E 矩阵快速幂+dp
传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...
- codeforces 149D Coloring Brackets (区间DP + dfs)
题目链接: codeforces 149D Coloring Brackets 题目描述: 给一个合法的括号串,然后问这串括号有多少种涂色方案,当然啦!涂色是有限制的. 1,每个括号只有三种选择:涂红 ...
- dp状态压缩
dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...
随机推荐
- 初识HTML01
什么是页面? 页面是基于浏览器的应用程序 页面是数据展示的载体,由浏览器和服务器共同执行产物. 浏览器的功能 向服务器发送用户请求指令 接收并解析数据展示给用户 服务器的功能 存储页面资源 处理并响应 ...
- 【UE4 C++ 基础知识】<3> 基本数据类型、字符串处理及转换
基本数据类型 TCHAR TCHAR就是UE4通过对char和wchar_t的封装 char ANSI编码 wchar_t 宽字符的Unicode编码 使用 TEXT() 宏包裹作为字面值 TCHAR ...
- AIApe问答机器人项目Scrum Meeting博客汇总
荡起双桨 Scrum Meeting 博客汇总 一.Alpha阶段 AIApe问答机器人Scrum Meeting 4.23 AIApe问答机器人Scrum Meeting 4.25 AIApe问答机 ...
- UltraSoft Scrum Meeting 博客汇总
一.Alpha阶段 UltraSoft - Alpha - Scrum Meeting 1 UltraSoft - Alpha - Scrum Meeting 2 UltraSoft - Alpha ...
- 【做题记录】[NOIP2011 提高组] 观光公交
P1315 [NOIP2011 提高组] 观光公交 我们想在 \(k\) 次加速每一次都取当前最优的方案加速. 考虑怎样计算对于每一条边如果在当前情况下使用加速器能够使答案减少的大小. 如果当前到达某 ...
- 树的子结构 牛客网 剑指Offer
树的子结构 牛客网 剑指Offer 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) # class TreeNode: # def __init_ ...
- sed 修改替换包含关键字的整行
查找关键字 user10 所在的行,替换整行内容为aaaaaaaaaa #sed -i "s/^.*user10.*$/aaaaaaaaaa/" useradd.txt
- LOTO虚拟示波器软件功能演示之——FIR数字滤波
本文章介绍一下LOTO示波器新出的功能--FIR数字滤波的功能. 在此之前我们先来了解一下带通滤波和带阻滤波.我们都知道每个信号是不同频率不同幅值正弦波的线性叠加,为了方便直接得观察到这种现象,就有了 ...
- 手撸markdown web server
先上效果图 在线预览 powered by kingreatwill/mdserve. markdown项目:https://github.com/kingreatwill/open 目的 经常写笔记 ...
- 基于 OSPF 路由的邻居邻接关系发现实践
1.实验目的 理解 OSPF 邻居关系和 OSPF 邻接关系的含义及差别 观察 OSPF 邻居邻接关系的建立过程 观察 OSPF 链路状态数据库的同步过程 2.实验原理 OSPF 网络中,路由器在发送 ...