UOJ497 新年的复读机
题意
给定
分析
考虑暴力区间 DP:设
考虑一个重要性质:每次只往外扩展一个数不劣。
感性证明:考虑四个数 (((12)3)4)
和 (1(2(34)))
之中必定有一个比 ((12)(34))
不劣。
首先将四个数同除它们的 gcd 没有影响。然后,令 (((12)3)4)
和 (1(2(34)))
都比 ((12)(34))
劣,推推式子抵消一下发现
由此做到
再考虑另一个重要性质:对于一个
证明:考虑
如果此时把这些分界点拿出来,然后枚举初始点,直接 DP 状态数是
我们可以将
考虑对这些区间做 DP,首先将这些区间按照长度排序,桶排鸡排都行。
考虑能转移到
最后介绍一下怎么求合法区间。
以固定右端点为例,考虑求出
const int maxn=2e5+5,maxm=2e7+5,inf=0x3f3f3f3f;
const long long llinf=0x3f3f3f3f3f3f3f3f;
int n,a[maxn],s[maxn];
inline int gcd(int x,int y){
return !y?x:gcd(y,x%y);
}
struct seg{
int l,r,g;
}b[maxm];
int cnt;
pii q[maxn],qq[maxn];
int qcnt;
vector<seg>vec[maxn];
int lstl[maxn],lstr[maxn],f[maxm];
inline void solve_the_problem(){
n=rd();
rep(i,1,n)a[i]=rd(),s[i]=s[i-1]+a[i];
rep(i,1,n){
rep(j,1,qcnt)q[j].se=gcd(q[j].se,a[i]);
q[++qcnt]=mp(i,a[i]);
int pcnt=0;
per(j,qcnt,1){
if(q[j].fi==1||q[j].fi==i||q[j+1].se!=q[j].se){
qq[++pcnt]=q[j];
}
}
qcnt=pcnt;
rep(j,1,qcnt)q[j]=qq[qcnt-j+1];
rep(j,1,qcnt){
b[++cnt]=(seg){q[j].fi,i,q[j].se};
}
}
qcnt=0;
per(i,n,1){
rep(j,1,qcnt)q[j].se=gcd(q[j].se,a[i]);
q[++qcnt]=mp(i,a[i]);
int pcnt=0;
per(j,qcnt,1){
if(q[j].fi==n||q[j].fi==i||q[j+1].se!=q[j].se){
qq[++pcnt]=q[j];
}
}
qcnt=pcnt;
rep(j,1,qcnt)q[j]=qq[qcnt-j+1];
rep(j,1,qcnt){
b[++cnt]=(seg){i,q[j].fi,q[j].se};
}
}
rep(i,1,cnt){
vec[b[i].r-b[i].l+1].emplace_back((seg){b[i].l,b[i].r,b[i].g});
}
cnt=0;
rep(i,1,n){
for(auto j:vec[i])b[++cnt]=j;
vec[i].clear(),vec[i].shrink_to_fit();
}
rep(i,1,cnt){
const int l=b[i].l,r=b[i].r,L=lstl[l],R=lstr[r];
if(l==r){
lstl[l]=lstr[r]=i,f[i]=0;
continue;
}
f[i]=min(f[L]+b[L].g*(r-b[L].r)+s[r]-s[b[L].r],f[R]+b[R].g*(b[R].l-l)+s[b[R].l-1]-s[l-1]);
lstl[l]=lstr[r]=i;
}
write(f[cnt]);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!