提交地址。


关于lyd给的倍增方法,即从当前枚举向后的$2^k$长度($k$从$1$开始),如果可行就将$k$加一以扩大范围,不可行时将范围不断减半直至$0$。

举个例子,假设当下在1,目标答案是13,那么枚举的范围变化情况是$2$,$4$,$8$,$16$(不行,且范围开始缩小),$12$,$14$(不行),$13$,$13$(范围缩小至0)。

并没有看出这样倍增有什么好处。复杂度可证也是$O(logN)$的,但是不是会带个2左右的常数么。。具lyd所说,当目标答案位置较近时会加快效率。

但是这不影响整体复杂度啊。。带着不很理解的态度看了例题才明白这种倍增姿势相较于二分或者从大到小二倍增的优势所在。


题意:数列$N \leqslant 500000$,求划分最少区间使得每段区间任选$M$对数字(不重复选,不够$M$对的时候能选多少选多少)的差的平方之和小于$K$。


首先很容易证明(cai ce)到对于一列数的最大的上述价值就是将最大数减最小数平方加上次大数减次小数平方加上......也就是排序后头尾相配。可以微调法证明任意一种其他策略不会更优。此贪心为关键之一。

然后因为满足要求的一段区间显然越长越好,所以从起点开始拓展,拓展到最远的地方记下来,反复接替拓展,一定是最小区间数。又因为答案随数列增长是有单调性的,所以可以二分检查找到最远的符合要求的右端点。

每次check时候对区间进行排序,加上二分以及区间数的复杂度,最坏$O(N^2log^2N)$。

可以发现,二分时候每次排序都是一个$O(NlogN)$,因为最坏可能答案在比较靠右的位置。这个时候,lyd给出的倍增方案就派上用场了。


lyd书上描述的倍增方法,总是将复杂度限制在$log($答案区间的长度$)$。假若我们采用这种倍增,那么每次枚举的区间最长长度假设为$K$,则找到这样一个区间的复杂度是$O(Klog^2K)$。(倍增一个$logK$,每次排序一个$KlogK$)而不是原来完整的N。

那么,每个区间的复杂度累加起来不会超过$O(Nlog^2N)$。很容易证。所以通过限制枚举次数在答案对数内,累加起来就比原来少一个log。这就是这种倍增优势。


但是$O(Nlog^2N)$仍然过不了。考虑到每次都要排序,前面已经可行的区间又被拉进来排了一次,显然浪费时间。于是可以只对当前试探的这段区间排序后,和原来已排好序的两个数列归并。归并完求代价,判断是否满足要求。

每次只对新的一小段排序,总体累加起来每次拓展的排序复杂度是$O(KlogK)$的(对于枚举过头了的区间,虽然不断缩小不断重复排序,但由于每次的排序复杂度折半,总体不会超过原来大区间的两倍)。

而$logK$次倍增每次复制需要$O(K)$,所以也是$O(KlogK)$.

最后,总体累加,复杂度$O(NlogN)$。

这题给予我们几个启发:二分和倍增都可用于有单调性的查找,有时候两者没有什么区别,但有时的check函数复杂度和答案位置有关倍增可以通过限制此条件使得总体复杂度优化掉。


代码写起来的话还是很少的。

WA记录

  • line61智障没考虑边界。
  • line49笔误。。
  • line59每次初始值。。哎可能是我倍增没有操作好
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define _dbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
namespace io{
const int SIZE = ( << ) + ;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - , c, qu[]; int f, qr;
#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
inline void flush (){fwrite (obuf, , oS - obuf, stdout);oS = obuf;}
inline void putc (char x){*oS ++ = x;if (oS == oT) flush ();}
template <class I>
inline void read(I &x) {for (f = , c = gc(); c < '' || c > ''; c = gc()) if (c == '-') f = -;
for (x = ; c <= '' && c >= ''; c = gc()) x = x * + (c & ); x *= f;}
template <class I>
inline void print (I x){
if (!x) putc (''); if (x < ) putc ('-'), x = -x;while(x) qu[++ qr] = x % + '', x /= ;while (qr) putc (qu[qr--]);}
struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io::read;
using io::putc;
using io::print;
const int N=+;
int a[N],tmp[N],b[N],c[N];//c:临时排序数组 b:已归并好的数组 tmp:临时归并数组
ll k;
int T,n,m,ans; inline void Merge(int L,int R,int r){
int i=L,j=R+;
for(register int k=L;k<=r;++k)
if(b[i]<c[j]&&i<=R||j>r)tmp[k]=b[i++];
else tmp[k]=c[j++];
}
inline ll calc(int L,int R,int r){
if(r==R)return k+;//_dbg(L,R),dbg(r);
for(register int i=R+;i<=r;++i)c[i]=a[i];
sort(c+R+,c+r+);
Merge(L,R,r);
ll ret=;//for(register int i=L;i<=r;++i)printf("%d ",tmp[i]);puts("");
for(register int i=L;i<=L+_min(m,(r-L+>>))-;++i)ret+=(tmp[r-i+L]-tmp[i])*1ll*(tmp[r-i+L]-tmp[i]);
return ret;
} int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
read(T);while(T--){
read(n),read(m),read(k);
for(register int i=;i<=n;++i)read(a[i]);
ans=;int L=,R=,p,r;
while(L<=n){
p=;b[L]=a[L];
while(p){
if(calc(L,R,r=_min(n,R+p))<=k){
for(register int i=L;i<=r;++i)b[i]=tmp[i];
R=r,p<<=;
}
else p>>=;
}
L=R+,R=L,++ans;
}
print(ans);putc('\n');
}
return ;
}

hihocoder1384/CH0601 Genius ACM[贪心+倍增+归并排序]的更多相关文章

  1. CH0601 Genius ACM【倍增】【归并排序】

    0601 Genius ACM 0x00「基本算法」例题 描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数 ...

  2. $CH0601\ Genius\ ACM$ 倍增优化DP

    ACWing Description 给定一个长度为N的数列A以及一个整数T.我们要把A分成若干段,使得每一段的'校验值'都不超过N.求最少需要分成几段. Sol 首先是校验值的求法: 要使得'每对数 ...

  3. ACM-ICPC Beijing 2016 Genius ACM(倍增+二分)

    描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数,如果 S 中的整 数不够 M 对,则取到不能取为止),使 ...

  4. AcWing:109. 天才ACM(倍增 + 归并排序)

    给定一个整数 MM,对于任意一个整数集合 SS,定义“校验值”如下: 从集合 SS 中取出 MM 对数(即 2∗M2∗M 个数,不能重复使用集合中的数,如果 SS 中的整数不够 MM 对,则取到不能取 ...

  5. hihocoder--1384 -- Genius ACM (倍增 归并)

    题目链接 1384 -- Genius ACM 给定一个整数 m,对于任意一个整数集合 S,定义“校验值”如下:从集合 S 中取出 m 对数(即 2*M 个数,不能重复使用集合中的数,如果 S 中的整 ...

  6. Contest Hunter 0601 Genius ACM

    Genius ACM Advanced CPU Manufacturer (ACM) is one of the best CPU manufacturer in the world. Every d ...

  7. [hihocoder #1384] Genius ACM 解题报告(倍增)

    题目链接:http://hihocoder.com/problemset/problem/1384 题目大意: 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M ...

  8. hihoCoder#1384 : Genius ACM

    对于一个固定的区间$[l,r]$,显然只要将里面的数字从小到大排序后将最小的$m$个和最大的$m$个配对即可. 如果固定左端点,那么随着右端点的右移,$SPD$值单调不降,所以尽量把右端点往右移,贪心 ...

  9. Codeforces 980E The Number Games 贪心 倍增表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9074226.html 题目传送门 - Codeforces 980E 题意 $\rm Codeforces$ ...

随机推荐

  1. cef加载flash的办法

    cef有2种加载flash插件的方式, 1,npapi,这种方式是调用系统自带的flash插件,由于有安全性方面的问题,已经被新版cef禁用. 2,ppapi,也就是 pepper flash,这是谷 ...

  2. 人工智能06 能计划的agent

    能计划的agent 存储与计算 响应agent的动作功能几乎没有做任何计算.从本质上讲,这些agent执行的动作或者由他们的设计者.或者通过学习.或者通过演化过程.或者由以上几方面的组合来选择给他们的 ...

  3. 华为HCNA乱学Round 9:VRRP

  4. elasticsearch 查询所有文档

    0.添加一个索引 curl -i -XPUT http://172.31.250.16:10004/test_index/user/1 -d '{ "name": "小明 ...

  5. Linux下安装双JDK环境与双服务器

    安装双JDK环境和双服务器,具体操作如下: (1)使用tar -xvf命令解压Tomcat: (2)在Tomcat服务器下的bin文件夹下的catalina.sh文件中的头部加入以下内容: (3)修改 ...

  6. C++多线程基础学习笔记(三)

    一.detach()大坑 上一篇随笔(二)中提到detach()是用来分离主线程和子线程的,那么需要考虑一个问题,就是如果主线程跑完了,主线程中定义的变量就会被销毁(释放内存),这时回收变量仍作为参数 ...

  7. Eclipse 新建.jsp页面后,页面头部标签报错的解决方法

    Eclipse 新建.jsp页面后,页面头部标签报错的解决方法 1.报错地方: 2.解决方法: .jsp页面右键==>BUild Path ==>Configure Build Path. ...

  8. Kinect开发-Hello Kinect

    置好开发环境后,首先测试下是否真的完成,也就是能够正常进行开发.此时,当然就得祭出Hello World大法! 1.首先创建一个WPF Application工程,之后添加对Microsoft.Kin ...

  9. Cypher查询在Neo4j中加载具有点数据类型属性的CSV文件

    我有一个CSV文件,标有3列,ID,纬度,经度.我想将CSV文件加载到Neo4j中并创建具有上述属性的节点.Location:属性应该是具有纬度和经度子属性的点数据类型. CSV是: ID,latit ...

  10. Global.asax文件

    转载:http://www.cnblogs.com/I-am-Betty/archive/2010/09/06/1819558.html 概述: Global.asax文件也叫做asp.net应用程序 ...