[关闭]
@xiaoziyao 2021-05-13T15:57:50.000000Z 字数 2571 阅读 886

CF1175G Yet Another Partiton Problem解题报告

解题报告


CF1175G Yet Another Partiton Problem解题报告:

题意

分析

代码

保留了一部分DEBUG内容,鬼知道我是怎么把二分斜率的地方写错的。

  1. #include<stdio.h>
  2. #include<queue>
  3. #define inf 1000000000
  4. using namespace std;
  5. const int maxn=20005,maxk=maxn*20;
  6. int n,k,now,lst,top,tot;
  7. int a[maxn],b[maxn],f[2][maxn],stk[maxn],lc[maxk],rc[maxk],ans[maxk],rt[maxn];
  8. deque<int>con[maxn];
  9. inline int calc(int id,int X){
  10. return a[id]*X+b[id];
  11. }
  12. inline int newnode(int x){
  13. tot++,lc[tot]=lc[x],rc[tot]=rc[x],ans[tot]=ans[x];
  14. return tot;
  15. }
  16. void update(int l,int r,int now,int pos){
  17. // printf("now=%d ",now);
  18. if(l==r){
  19. // printf("\n!!!!!!!!!!!!!!! %d %d %d %d\n",l,r,now,pos);
  20. if(calc(ans[now],l)>calc(pos,l))
  21. ans[now]=pos;
  22. return ;
  23. }
  24. int mid=(l+r)>>1;
  25. if(calc(ans[now],mid)>calc(pos,mid))
  26. swap(ans[now],pos);
  27. if(calc(ans[now],l)>calc(pos,l))
  28. lc[now]=newnode(lc[now]),update(l,mid,lc[now],pos);
  29. else rc[now]=newnode(rc[now]),update(mid+1,r,rc[now],pos);
  30. }
  31. int query(int l,int r,int now,int X){
  32. if(l==r)
  33. return calc(ans[now],X);
  34. int mid=(l+r)>>1,res;
  35. if(X<=mid)
  36. res=query(l,mid,lc[now],X);
  37. else res=query(mid+1,r,rc[now],X);
  38. return min(res,calc(ans[now],X));
  39. }
  40. inline int x(int p){
  41. return p;
  42. }
  43. inline int y(int p){
  44. return f[lst][p];
  45. }
  46. inline double slope(int a,int b){
  47. return x(a)==x(b)? (y(a)>y(b)? inf:-inf):1.0*(y(a)-y(b))/(x(a)-x(b));
  48. }
  49. void merge_convex(int a,int b){
  50. int flg=0;
  51. if(con[a].size()>con[b].size()){
  52. while(!con[b].empty()){
  53. int p=con[b].back();
  54. while(con[a].size()>1&&slope(con[a][1],p)>=slope(con[a][1],con[a][0]))
  55. con[a].pop_front();
  56. con[a].push_front(p),con[b].pop_back();
  57. }
  58. }
  59. else{
  60. for(int i=0;i<con[a].size();i++){
  61. int p=con[a][i];
  62. while(con[b].size()>1&&slope(p,con[b][con[b].size()-2])<=slope(con[b].back(),con[b][con[b].size()-2]))
  63. con[b].pop_back();
  64. con[b].push_back(p);
  65. }
  66. con[a].clear(),swap(con[a],con[b]);
  67. }
  68. }
  69. int find(int p,int X){
  70. int L=1,R=con[p].size()-1;
  71. // for(int i=0;i<con[p].size();i++)
  72. // printf("%d(%d) ",con[p][i],f[lst][con[p][i]]);
  73. // puts("");
  74. while(L<=R){
  75. int mid=(L+R)>>1;
  76. if(slope(con[p][mid],con[p][mid-1])<1.0*X)
  77. L=mid+1;
  78. else R=mid-1;
  79. }
  80. // printf("L=%d(%d,%d)\n",L-1,con[p][L-1],f[lst][con[p][L-1]]-(con[p][L-1]-1)*X);
  81. return f[lst][con[p][L-1]]-(con[p][L-1]-1)*X;
  82. }
  83. int main(){
  84. scanf("%d%d",&n,&k);
  85. int tmp=0;
  86. a[0]=0,b[0]=inf;
  87. for(int i=1;i<=n;i++){
  88. scanf("%d",&a[i]);
  89. tmp=max(tmp,a[i]),f[0][i+1]=i*tmp;
  90. }
  91. now=1,lst=0;
  92. for(int i=2;i<=k;i++){
  93. top=tot=0;
  94. for(int j=i;j<=n;j++){
  95. con[j].clear(),con[j].push_back(j);
  96. while(top>0&&a[j]>=a[stk[top]])
  97. merge_convex(j,stk[top]),top--;
  98. rt[j]=newnode(rt[stk[top]]),stk[++top]=j;
  99. // printf("rt[j]=%d\n",rt[j]);
  100. b[j]=find(j,a[j]),update(1,n,rt[j],j),f[now][j+1]=query(1,n,rt[j],j);
  101. // printf("i=%d j=%d f[now][j+1]=%d b=%d a=%d\n",i,j,f[now][j+1],b[j],a[j]);
  102. }
  103. lst=now,now^=1;
  104. }
  105. printf("%d\n",f[lst][n+1]);
  106. return 0;
  107. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注