【BZOJ4167】永远的竹笋采摘

题解:我们考虑有多少点对(a,b)满足a与b的差值是[a,b]中最小的。以为是随机数据,这样的点对数目可能很少,实测是O(n)级别的,那么我们已知了有这么多可能对答案造成贡献的点对,如何将它们求出来呢?

考虑分块,因为所有数大小在[1,n]中,我们可以对于每个块,预处理出整个块到所有数的最小差值。然后从右往左枚举每一个点,再枚举右面所有的块,如果这个块到当前数的差值比之前的要小,那就暴力进入块中扫一遍。与此同时,我们需要知道是否已经存在这样的点对,被当前的点对完全包含且差值更小。这个可以用树状数组搞定。

最后,我们得到所有的点对,问题就变成了在数轴上选取k个互不相交的线段,使得线段权值和最小。跑个DP就行了。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <cmath>
  5. #include <algorithm>
  6. using namespace std;
  7. const int maxn=60010;
  8. int n,m,B,cnt,minn;
  9. int s[maxn],v[maxn],p[maxn];
  10. int cls[250][maxn],f[2][maxn],to[500000],next[500000],head[maxn],val[500000];
  11. int rd()
  12. {
  13. int ret=0,f=1; char gc=getchar();
  14. while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
  15. while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
  16. return ret*f;
  17. }
  18. int z(int x)
  19. {
  20. return x>0?x:-x;
  21. }
  22. void updata(int x,int val)
  23. {
  24. for(int i=x;i<=n;i+=i&-i) s[i]=min(s[i],val);
  25. }
  26. int query(int x)
  27. {
  28. int i,ret=1<<30;
  29. for(i=x;i;i-=i&-i) ret=min(ret,s[i]);
  30. return ret;
  31. }
  32. void test(int a,int b)
  33. {
  34. int c=z(v[b]-v[a]);
  35. a++,b++,minn=min(minn,c);
  36. if(query(b)<=c) return ;
  37. updata(b,c);
  38. to[cnt]=a,val[cnt]=c,next[cnt]=head[b],head[b]=cnt++;
  39. }
  40. int main()
  41. {
  42. //freopen("bz4168.in","r",stdin);
  43. n=rd(),m=rd(),B=ceil(sqrt(n));
  44. int i,j,k,last;
  45. for(i=0;i<n;i++) v[i]=rd();
  46. memset(cls,0x3f,sizeof(cls));
  47. memset(s,0x3f,sizeof(s));
  48. for(i=0;i<n;i+=B)
  49. {
  50. for(j=i;j<i+B&&j<n;j++) p[v[j]]=1;
  51. for(last=-1<<30,j=1;j<=n;j++) cls[i/B][j]=min(cls[i/B][j],j-last),last=p[j]?j:last;
  52. for(last=1<<30,j=n;j>=1;j--) cls[i/B][j]=min(cls[i/B][j],last-j),last=p[j]?j:last;
  53. for(j=i;j<i+B&&j<n;j++) p[v[j]]=0;
  54. }
  55. memset(head,-1,sizeof(head));
  56. for(i=n-1;i>=0;i--)
  57. {
  58. minn=1<<30;
  59. for(j=i+1;j<i/B*B+B&&j<n;j++) if(v[j]!=v[i]&&z(v[j]-v[i])<minn) test(i,j);
  60. for(j=i/B+1;j*B<n;j++) if(cls[j][v[i]]<minn) for(k=j*B;k<j*B+B&&k<n;k++) if(v[k]!=v[i]&&z(v[k]-v[i])<minn) test(i,k);
  61. }
  62. for(k=1;k<=m;k++)
  63. {
  64. for(i=0;i<=n;i++) f[k&1][i]=1<<30;
  65. for(i=1;i<=n;i++)
  66. {
  67. f[k&1][i]=f[k&1][i-1];
  68. for(j=head[i];j!=-1;j=next[j]) f[k&1][i]=min(f[(k&1)^1][to[j]-1]+val[j],f[k&1][i]);
  69. }
  70. }
  71. printf("%d\n",f[m&1][n]);
  72. return 0;
  73. }

【BZOJ4167】永远的竹笋采摘 分块+树状数组的更多相关文章

  1. 【BZOJ 3295】动态逆序对 - 分块+树状数组

    题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...

  2. 【bzoj2141】排队 分块+树状数组

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别, ...

  3. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  4. 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu

    https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...

  5. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  6. 【XSY2111】Chef and Churus 分块 树状数组

    题目描述 有一个长度为\(n\)的数组\(A\)和\(n\)个区间\([l_i,r_i]\),有\(q\)次操作: \(1~x~y\):把\(a_x\)改成\(y\) \(2~x~y\):求第\(l\ ...

  7. BZOJ3787:Gty的文艺妹子序列(分块,树状数组)

    Description Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道: “在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢.你还能求出某个区间中妹子们美丽度的逆序对 ...

  8. 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)

    4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...

  9. 【xsy2111】 【CODECHEF】Chef and Churus 分块+树状数组

    题目大意:给你一个长度为$n$的数列$a_i$,定义$f_i=\sum_{j=l_i}^{r_i} num_j$. 有$m$个操作: 操作1:询问一个区间$l,r$请你求出$\sum_{i=l}^{r ...

随机推荐

  1. Android项目搭建最常用的架构解密

    在完成android项目的时候第一步都是要搭建架构,下面我们来展示一下最常用的架构结构的: 源码下载地址: https://download.csdn.net/download/heishuai123 ...

  2. CSU 1785: 又一道简单题

    1785: 又一道简单题 Submit Page   Summary   Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 602   ...

  3. Codeforces 761D Dasha and Very Difficult Problem(贪心)

    题目链接 Dasha and Very Difficult Problem 求出ci的取值范围,按ci排名从小到大贪心即可. 需要注意的是,当当前的ci不满足在这个取值范围内的时候,判为无解. #in ...

  4. lock与monitor的区别

    1.Lock 只能对引用对象加锁 Lock锁定区间内可以对锁定值修改而不发生运行时错误,通常也会采用此种修改方式.这种方式又有点类同于使用Monitor.Wait取得资源,并对这个资源进行操作. 用法 ...

  5. Data Leakage 因果性

    参考这篇: https://blog.csdn.net/jiandanjinxin/article/details/54633475 再论数据科学竞赛中的Data Leakage 存在和利用这种倒‘因 ...

  6. js aop 拦载实现

    var run = function(){ //is run } var aopBefore = function(){ //aopBefore } var tmpFn=run; run = func ...

  7. 2017.04.20 Adams仿真介绍

    Adams 仿真 | 验证"隐性机器人模型"概念,提高视觉伺服精度 产品:Adams行业:科研优势: 1.Adams 仿真可精确预测机器人的位置和方位 2.仿真在理论工作验证中起着 ...

  8. 【设计模式】工厂方法(FactoryMethod)模式

    看不见PPT的请自行解决DNS污染问题. 相关类的代码: namespace FactoryPatternConsole.Model { public class Address { public s ...

  9. C#托付之愚见

    C#托付起源 近期參加实习和奔走于各大招聘会,被问及非常多技术方面的问题.C#问的较多的就是托付和linq. linq之前已经写过一篇文章,能够參见 http://blog.csdn.net/yzys ...

  10. Foreach嵌套Foreach速度慢优化方案

    有时候这样的效率还可以,但是只要牵涉到操作数据库,那就GAMEOVER.. 最近在维护项目,一个Foreach循环,4分半才能出来结果. 代码: foreach ($content as $key = ...