hihocoeder1384

算法竞赛进阶指南上的题目

我们肯定是吧最大值和最小值匹配,次大值和次小值匹配以此类推

首先,类似于区间覆盖的思想,我们对于一个\(L\),找到最大的满足条件的\(R\)

之后把\(R + 1\)作为下一个\(L\)继续这个操作

现在,问题转化成了我们如何寻找最大的\(R\)

一个比较明显的思路就是去二分,但是二分时间复杂度不对

因为如果每次只能前进一格,二分时间复杂度就变成了\(n^2\log{n}\)

考虑倍增的思想

我们对于每个\(L\)

初始设置\(R= L - 1,p = 1\)

之后求加上\([R + 1,R + p]\)时候合法

合法的话 \(p = p \times 2\)

否则 \(p = p / 2\)

每次暴力判断新加入的区间是否合法

可以证明这样时间复杂度

为\(n\log^2{n}\)

之后发现,对于新加进来的区间,我们只需要把它排序,然后和原有的区间进行归并即可

时间复杂度就变成了\(n\log n\)

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<queue>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<cctype>
  7. #include<vector>
  8. #include<ctime>
  9. #include<cmath>
  10. #define LL long long
  11. #define pii pair<int,int>
  12. #define mk make_pair
  13. #define fi first
  14. #define se second
  15. #define min std::min
  16. #define max std::max
  17. const int N = 5e5 + 3;
  18. int a[N];
  19. int n,m;LL k;
  20. std::vector <int> A,B,G;
  21. inline LL read(){
  22. LL v = 0,c = 1;char ch = getchar();
  23. while(!isdigit(ch)){
  24. if(ch == '-') c = -1;
  25. ch = getchar();
  26. }
  27. while(isdigit(ch)){
  28. v = v * 10 + ch - 48;
  29. ch = getchar();
  30. }
  31. return v * c;
  32. }
  33. inline bool check(int l,int r){
  34. B.clear(),G.clear();
  35. for(int i = l;i <= r;++i) B.push_back(a[i]);
  36. sort(B.begin(),B.end());
  37. int now1 = 0;int now2 = 0;
  38. while(now1 < A.size() && now2 < B.size()){
  39. if(A[now1] < B[now2]) G.push_back(A[now1++]);
  40. else G.push_back(B[now2++]);
  41. }
  42. while(now1 < A.size()) G.push_back(A[now1++]);
  43. while(now2 < B.size()) G.push_back(B[now2++]);
  44. LL res = 0;
  45. now1 = 0,now2 = G.size() - 1;
  46. for(int cnt = 0;cnt < m && now1 < now2;now1++,now2--,cnt++) res += 1ll * (G[now1] - G[now2]) * (G[now1] - G[now2]);
  47. if(res <= k){
  48. A = G;
  49. return 1;
  50. }
  51. else return 0;
  52. }
  53. int main(){
  54. // freopen("A.in","r",stdin);
  55. // freopen("A1.out","w",stdout);
  56. int T = read();
  57. while(T--){
  58. int ans = 0;
  59. n = read(),m = read(),k = read();
  60. for(int i = 1;i <= n;++i) a[i] = read();
  61. int l = 1,r = 0;
  62. while(l <= n){
  63. int p = 1;
  64. A.clear();
  65. while(p){
  66. int t = min(n,r + p);
  67. if(check(r + 1,t)){
  68. r = t;
  69. if(t == n) break;
  70. p <<= 1;
  71. }
  72. else p >>= 1;
  73. }
  74. l = r + 1;
  75. ans++;
  76. }
  77. printf("%d\n",ans);
  78. }
  79. return 0;
  80. }
  81. /*
  82. 1
  83. 10 2 10
  84. 4 1 3 2 1 3 2 1 3 4
  85. */

hihocoeder1384的更多相关文章

随机推荐

  1. Directx11教程(8) 一个新的camera类

    原文:Directx11教程(8) 一个新的camera类      本章我们将替换掉CameraClass类,实现一个稍微靠谱点的摄像机类.并通过Q,W,E,A,S,D,Z,X,C等按键实现摄像机的 ...

  2. python KMP算法介绍

  3. python 并发之进程

    一.什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实 ...

  4. MaxCompute如何对SQL查询结果实现分页获取

    由于MaxCompute SQL本身不提供类似数据库的select * from table limit x offset y的分页查询逻辑.但是有很多用户希望在一定场景下能够使用获取类似数据库分页的 ...

  5. docker学习笔记(总纲)

    阿里容器Docker简介 什么是Docker 为什么要用Docker 基本认识 Docker EE/Docker CE简介与版本规划 镜像 容器 仓库 数据卷 阿里容器服务的基本概念与其它名词解释 C ...

  6. Android EditText____TextchangedListener

    今天在做APP的时候有个需求: EditText 动态监听内容变化如果长度为6时(就是看是不是验证码) 判断是否正确 正确就跳到下一个Activity,但是在Activity.finish()的时候, ...

  7. this 、静态变量

    /*作者:qingfeng日期:2017/2/18功能:this,静态变量(类变量)*/class Demo3_2{    public static void main(String args[]) ...

  8. iOS打包上传ipa文件时,报错<ERROR ITMS-90096: "Your binary is not optimized for iPhone 5 - New iPhone apps......>的解决方案

    很长一段时间习惯了用企业级证书发布,最近的新项目使用Xcode 9.1发布到AppStore时遇到了一个小问题(emm..其实问题跟Xcode版本没关系,我也不知道为什么要声明这个233),如下: E ...

  9. oralce函数 count(*|[distinct|all]x)

    [功能]统计数据表选中行x列的合计值. [参数] *表示对满足条件的所有行统计,不管其是否重复或有空值(NULL) all表示对所有的值统计,默认为all distinct只对不同的值统计, 如果有参 ...

  10. Python基础:17类和实例之一(类属性和实例属性)

    1:类通常在一个模块的顶层进行定义.对于Python来说,声明与定义类是同时进行的. 2:类属性仅与其类相绑定,类数据属性仅当需要有更加“静态”数据类型时才变得有用,这种属性是静态变量.它们表示这些数 ...