Codeforces Round #445 Div1 E:Mod Mod Mod (平衡树优化DP)
来源:互联网 发布:家庭千兆网络布线 编辑:程序博客网 时间:2024/06/05 21:12
题目传送门:http://codeforces.com/contest/889/problem/E
题目大意:有一个长度为n的序列a。定义函数
题目分析:一开始想错了,以为是道水题。容易发现最优解必定存在一个i,使得最初的x不断取模下去,到第i位恰好为
然而往左走贪心地变大是错的,举个反例:
a={13,19,8,2,3,8,10,7,12,6}
当i=4的时候,贪心地往左走,前四个值为{7,7,7,1},然而最优解应该是{11,11,3,1}。
正解的做法是一个很神奇的DP(以下为题解翻译)。设
不会用STL的map?还不快像我一样手写Treap!
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=200100;const int Lg=40;const long long M1=998244353;const long long M2=1000000007;const long long M3=1333333331;typedef long long LL;LL seed;struct Tnode{ LL val,cnt; int fix; Tnode *lson,*rson;} tree[maxn*Lg];Tnode *Root=NULL;int cur=-1;LL a[maxn];int n;LL ans=0;int Rand(){ seed=(seed*M1+M2)%M3; return (int)seed;}Tnode *New_node(LL Val,LL Cnt){ cur++; tree[cur].val=Val; tree[cur].cnt=Cnt; tree[cur].fix=Rand(); tree[cur].lson=tree[cur].rson=NULL; return tree+cur;}void Right_turn(Tnode *&P){ Tnode *W=P->lson; P->lson=W->rson; W->rson=P; P=W;}void Left_turn(Tnode *&P){ Tnode *W=P->rson; P->rson=W->lson; W->lson=P; P=W;}void Insert(Tnode *&P,LL Val,LL Cnt){ if (!P) P=New_node(Val,Cnt); else if ( Val<P->val || ( Val==P->val && Cnt<P->cnt ) ) { Insert(P->lson,Val,Cnt); if ( P->lson->fix < P->fix ) Right_turn(P); } else { Insert(P->rson,Val,Cnt); if ( P->rson->fix < P->fix ) Left_turn(P); }}Tnode *Last(Tnode *P){ if (!P->rson) return P; return Last(P->rson);}void Delete(Tnode *&P,LL Val,LL Cnt){ if ( Val==P->val && Cnt==P->cnt ) if (P->lson) if (P->rson) if ( P->lson->fix < P->rson->fix ) { Right_turn(P); Delete(P->rson,Val,Cnt); } else { Left_turn(P); Delete(P->lson,Val,Cnt); } else P=P->lson; else P=P->rson; else if ( Val<P->val || ( Val==P->val && Cnt<P->cnt ) ) Delete(P->lson,Val,Cnt); else Delete(P->rson,Val,Cnt);}void Dfs(Tnode *P){ if (!P) return; Dfs(P->lson); Dfs(P->rson); ans=max(ans,(long long)n*P->val+P->cnt);}int main(){ freopen("E.in","r",stdin); freopen("E.out","w",stdout); scanf("%d",&n); seed=n; for (int i=1; i<=n; i++) scanf("%I64d",&a[i]); Insert(Root,a[1]-1LL,0LL); for (int i=2; i<=n; i++) { LL Max=-1; Tnode *P=Last(Root); while ( P->val>=a[i] ) { LL Val=P->val,Cnt=P->cnt; Delete(Root,Val,Cnt); LL temp=(Val+1LL)/a[i]-1LL; Max=max(Max,Cnt+temp*(long long)(i-1)*a[i]); if (Val%a[i]!=a[i]-1LL) temp++; Insert(Root,Val%a[i],Cnt+temp*(long long)(i-1)*a[i]); P=Last(Root); } if (Max>=0) Insert(Root,a[i]-1LL,Max); } Dfs(Root); printf("%I64d\n",ans); //printf("%d\n",sizeof(tree)/1024/1024); return 0;}
- Codeforces Round #445 Div1 E:Mod Mod Mod (平衡树优化DP)
- Codeforces Round #445 (Div. 1, based on Technocup 2018 Elimination Round 3) E. Mod Mod Mod
- MOD
- mod..........
- Mod
- Mod
- mod
- DECODE,trunc,ROUND,mod
- codeforces 893E(组合数学&组合数取mod)
- HRBUST2381:MOD(二分)
- Mod (二分法)
- BIG MOD
- MOD 运算
- mod运算
- 三国群英mod
- mod 函数
- mod等式
- mod fib
- Viewpager的轮播
- 操作系统 — 进程的退出(exit)
- HDOJ1985 Conversions
- 综合知识点练习
- 每天一个linux命令(41):ps命令
- Codeforces Round #445 Div1 E:Mod Mod Mod (平衡树优化DP)
- 简单的卷积神经网络
- AngularJS入门
- Tomcat
- 【JZ2440】自我学习记录【知识点1】【操作系统理解】
- 每天一个linux命令(42):kill命令
- credit card fraud detection
- 专业英语(2)
- android关于provider包冲突的问题