干掉这道题的那一刻,我只想说:我终于**的AC了!!!

最终内存1344K,耗时10282ms,比起归并树、划分树以及其他各种黑科技,这个成绩并不算光彩⊙﹏⊙

但至少,从最初的无数次TLE到最终的AC,这过程见证了一个二分算法的艰辛优化

感谢国家,感谢XXTV,感谢《挑战程序设计竞赛》~( ̄▽ ̄)~*

先贴代码:

 ;
 ;
 ;
 ;
 const int maxV=1e9;

 int bucket[bktCount][bktSize];
 int unOrdered[bktSize*bktCount];
 int ordered[bktSize*bktCount];
 int N,K;

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 void init()
 {
     scanf("%d%d",&N,&K);
     memset(bucket[N>>bktDigit],0x7f,sizeof(bucket[N>>bktDigit]));
     ;i<N;i++)
     {
         scanf("%d",unOrdered+i);
         ordered[i]=unOrdered[i];
         bucket[i>>bktDigit][i&bktMaxIdx]=unOrdered[i];
     }

     using std::sort;
     int bktUsed=N>>bktDigit;
     sort(ordered,ordered+N);
     ;i<=bktUsed;i++) sort(bucket[i],bucket[i]+bktSize);
 }

 inline void enumerate(int _rangeL,int _rangeR,int _val,int& _notMore)
 {
     for(int i=_rangeL;i<=_rangeR;i++)
         if(unOrdered[i]<=_val) ++_notMore;
 }

 inline void countBucket(int _bktIdx,int _val,int& _notMore)
 {
     using std::upper_bound;

     int* ub=upper_bound(bucket[_bktIdx],bucket[_bktIdx]+bktSize,_val);
     _notMore+=(ub-bucket[_bktIdx]);
 }

 int ask(int _rangeL,int _rangeR,int _k) //k-th smallest
 {
     int digitL=_rangeL>>bktDigit;
     int digitR=_rangeR>>bktDigit;
     ;
     ;

     while(vL<vR)
     {
         ;
         ;
         if(digitL==digitR)
             enumerate(_rangeL,_rangeR,ordered[midV],notMore);
         else
         {
             ;i<digitR;i++)
                 countBucket(i,ordered[midV],notMore);
             enumerate(_rangeL,((digitL+)<<bktDigit)-,ordered[midV],notMore);
             enumerate(digitR<<bktDigit,_rangeR,ordered[midV],notMore);
         }

         ;
         else vR=midV;
     }
     return ordered[vL];
 }

 int main()
 {
     init();
     ;i<K;i++)
     {
         int l,r,k;
         scanf("%d%d%d",&l,&r,&k);
         printf(,r-,k));
     }
     ;
 }

1、为什么统计notMore,而不是统计less或者两者都统计?

二分的过程中,缩减区间的关键是:

1、必须使可能成为最终解的值保留在二分区间中

2、每一次都必须使区间大小的确被缩减,以防陷入死循环

在这道题中,某个值x为解的条件是:less(x)<x && notMore(x)>=x

如果统计Less的话,上面的代码很难是保证第一条的

而如果两者都统计的话,表面上当x满足条件时即可跳出,可以减少二分所需的时间

但是事实上,这样做的代价就是统计的时间复杂度常数乘以2,总的来说得不偿失(会TLE)

2、二分的对象是什么?可否把maxValue和minValue作为二分的对象?

Answer:NO!!!

正确的做法是将原数组排好序,然后对这个有序数组二分

理由很简单:范围小。二分区间长不会超过1e5

如果对数值本身二分的话,minValue和maxValue最坏时分别会达到-1e9和+1e9,二分的时间代价是前者的1.9倍

3、平方分割必须是严格的么?

Answer:NO(*^__^*)(论如何用标点和颜文字表达语气( ̄. ̄))

设数据规模为N,每个桶的大小为B,则单次询问的时间复杂度为: O ( (N / B ) * log B + B )

当B = O ( ( N * log N ) ^ 0.5 ) 时,总的时间复杂度会比严格的平方分割小一些

代码中将B取为了1024正是为此。(顺便也方便了位运算)

B取512时效率会相对变差,B取256时干脆TLE

这道题更好的做法是归并树,比归并树还好的做法是划分树,不过这都是后话了,有时间慢慢填坑

POJ2104 K-th Number 静态区间第k最值 平方分割的更多相关文章

  1. POJ2104 K-th Number —— 静态区间第k小

    题目链接:http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Sub ...

  2. poj2104&&poj2761 (主席树&&划分树)主席树静态区间第k大模板

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 43315   Accepted: 14296 Ca ...

  3. HDU3473--Minimum Sum(静态区间第k大)

    Minimum Sum Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  4. 数据结构2 静态区间第K大/第K小

    给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...

  5. Dynamic Rankings || 动态/静态区间第k小(主席树)

    JYF大佬说,一星期要写很多篇博客才会有人看 但是我做题没有那么快啊QwQ Part1 写在前面 区间第K小问题一直是主席树经典题=w=今天的重点是动态区间第K小问题.静态问题要求查询一个区间内的第k ...

  6. 主席树初步学习笔记(可持久化数组?静态区间第k大?)

    我接触 OI也快1年了,然而只写了3篇博客...(而且还是从DP跳到了主席树),不知道我这个机房吊车尾什么时候才能摸到大佬们的脚后跟orz... 前言:主席树这个东西,可以说是一种非常畸形的数据结构( ...

  7. 静态区间第k大(归并树)

    POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...

  8. 主席树学习笔记(静态区间第k大)

    题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输出 ...

  9. 主席树(静态区间第k大)

    前言 如果要求一些数中的第k大值,怎么做? 可以先就这些数离散化,用线段树记录每个数字出现了多少次. ... 那么考虑用类似的方法来求静态区间第k大. 原理 假设现在要有一些数 我们可以对于每个数都建 ...

随机推荐

  1. git 添加忽略文件

    使用github for windows客户端添加.gitignore文件:   如下图所示,在github客户端可以看到未提交的更改列表 随便选中一个文件,右链,选择ignore file. 然后会 ...

  2. 数据结构(平衡树,树分治,暴力重构):WC 2014 紫荆花之恋

    [题目描述] 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来. 仔细看看的话,这棵大树实际上是一个带权 ...

  3. 关于fixed-point

    今天又出现了shader的问题,编译到真机效果就没了,后来仔细还是因为浮点数精度的问题,后来仔细查找了些资料,才发现自己太粗心,没有看清楚 fixed-point 数据类型就乱用,这是个范围在 [-1 ...

  4. Using QEMU for Embedded Systems Development

    http://www.opensourceforu.com/2011/06/qemu-for-embedded-systems-development-part-1/ http://www.opens ...

  5. 当前jQuery Mobile支持的6种页面切换方式

    切换方式 data-transition属性值 横向幻灯方式 slide 自上向下幻灯方式 slideup 自下向上幻灯方式 slidedown 中央弹出 pop 淡入淡出 fade 旋转弹出 fli ...

  6. POJ3186:Treats for the Cows(区间DP)

    Description FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for gi ...

  7. iOS-实现映客首页TabBar和滑动隐藏NavBar和TabBar

    之前在做直播的时候,参照了映客App,发现其首页的效果还挺不错,在网上找了一下相关仿映客App代码和博客,大部分都是说如何播放直播流和推流,对于UI这块甚少,所以我自己花了点时间研究了一下映客的首页U ...

  8. HDU 2191 (13.12.2)

    悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  9. sdut-2725-The Urge to Merge-状压DP

    把数组竖起来,从上往下走. 如果当前位置是竖着乘的,那么第一个点标记为1.否则标记为0. 样例最终的状态为: 0 0 1 0 1 0 1 0 0 0 0 0 #include<iostream& ...

  10. [Javascript] An Introduction to JSPM (JavaScript Package Manager)

    JSPM can handle installed packages, transpiling ES6, and bundling all from the command-line. This vi ...