题意:有n个数。m个询问(l,r,k),问在区间[l,r] 有多少个数小于等于k。

划分树——查找区间第k大的数。。。。

利用划分树的性质。二分查找在区间[l,r]小于等于k的个数。

假设在区间第 i 大的数tmp>k,则往下找,假设tmp<k,往上找。

 

#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
#define INF 1e8
#define eps 1e-8
#define LL long long
#define N 100010
#define mod 1000000007 int a[N],s[N],t[20][N],num[20][N],n,m; void build(int c,int l,int r)
{
if(l==r) return;
int mid=(l+r)/2;
int lm=mid-l+1,lp=l,rp=mid+1;
for(int i=l;i<=r;i++)
lm-=s[i]<s[mid];
for(int i=l;i<=r;i++)
{
if(i==l)
num[c][i]=0;
else num[c][i]=num[c][i-1];
if(t[c][i]==s[mid])
{
if(lm)
{
lm--;
num[c][i]++;
t[c+1][lp++]=t[c][i];
}
else t[c+1][rp++]=t[c][i];
}
else if(t[c][i]<s[mid])
{
num[c][i]++;
t[c+1][lp++]=t[c][i];
}
else t[c+1][rp++]=t[c][i];
}
build(c+1,l,mid);
build(c+1,mid+1,r);
} int query(int c,int l,int r,int ql,int qr,int k)
{
if(l==r)
return t[c][l];
int s,ss,mid=(l+r)/2;
if(ql==l)
s=0,ss=num[c][qr];
else s=num[c][ql-1],ss=num[c][qr]-num[c][ql-1];
if(k<=ss)
return query(c+1,l,mid,l+s,s+l+ss-1,k);
else return query(c+1,mid+1,r,mid+1+ql-l-s,mid+1+qr-l-s-ss,k-ss);
} int main()
{
int T,ca=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s[i]=t[0][i]=a[i];
}
sort(s+1,s+n+1);
build(0,1,n);
printf("Case %d:\n",ca++);
while(m--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
l++;r++;
if(query(0,1,n,l,r,r-l+1)<=k)
printf("%d\n",r-l+1);
else if(query(0,1,n,l,r,1)>k)
puts("0");
else
{
int ll=0,rr=r-l+1,mid;
while(ll<=rr)
{
mid=(ll+rr)>>1;
int tmp=query(0,1,n,l,r,mid);//假设在区间[l,r]第mid大的数大于k,rr=mid-1
if(tmp>k)
rr=mid-1;
else ll=mid+1;//否则ll=mid+1
}
printf("%d\n",ll-1);
}
}
}
return 0;
}
/*
1
10 10
0 5 2 7 5 4 3 8 7 7
2 8 6
3 5 0
1 3 1
1 9 4
0 1 0
3 5 5
5 5 1
4 6 3
1 5 7
5 7 3
*/

HDU 4417 划分树+二分的更多相关文章

  1. HDU 4417 (划分树+区间小于k统计)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目大意:给定一个区间,以及一个k值,求该区间内小于等于k值的数的个数.注意区间是从0开始的 ...

  2. hdu 4417 划分树

    思路:二分枚举区间第k大.用划分树查找是否符合要求的高度. #include<iostream> #include<algorithm> #include<cstdio& ...

  3. HDU 4417 划分树写法

    Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability re ...

  4. sdut 2610:Boring Counting(第四届山东省省赛原题,划分树 + 二分)

    Boring Counting Time Limit: 3000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述     In this problem you a ...

  5. HDU-4417 Super Mario,划分树+二分!

    Super Mario 这个题也做了一天,思路是很清晰,不过二分那里写残了,然后又是无限RE.. 题意:就是查询区间不大于k的数的个数. 思路:裸划分树+二分答案.将区间长度作为二分范围.这个是重点. ...

  6. Super Mario HDU 4417 主席树区间查询

    Super Mario HDU 4417 主席树区间查询 题意 给你n个数(编号从0开始),然后查询区间内小于k的数的个数. 解题思路 这个可以使用主席树来处理,因为这个很类似查询区间内的第k小的问题 ...

  7. HDU 4417 - Super Mario ( 划分树+二分 / 树状数组+离线处理+离散化)

    题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...

  8. 【划分树+二分】HDU 4417 Super Mario

    第一次 耍划分树.. . 模板是找第k小的 #include <stdio.h> #include <string.h> #include <stdlib.h> # ...

  9. hdu4417 划分树+二分

    //Accepted 14796 KB 453 ms //划分树 //把查询的次数m打成n,也是醉了一晚上!!! //二分l--r区间第k大的数和h比较 #include <cstdio> ...

随机推荐

  1. iOS手势UIGestureRecognizer的使用失效问题

    问题:视图正常展示在界面中,父层是放在window上的,底部的一个控件的点击事件失效(所有设置都正常) 解决思路:虽然视图能够正常展示,但是发现父类视图的底部尺寸比子类的视图的尺寸小,也就是说上层视图 ...

  2. Ansible 删除多个文件或目录

    翻译和转载该网页内容 http://www.mydailytutorials.com/ansible-delete-multiple-files-directories-ansible/ 背景 ans ...

  3. 几何【P2313】 [HNOI2005]汤姆的游戏

    顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述--->p2313 [HNOI]汤姆的游戏 分析 说不上是分析. 数据范围给出来,这题明显暴力啊emmm. 个人认为的坑点. 这题不 ...

  4. Oracle remove duplicate

    DELETE FROM your_table WHERE rowid not in (SELECT MIN(rowid) FROM your_table GROUP BY column1, colum ...

  5. Qt如何学习(参考官方文档)

    Designers who are familiar with web development can start with QML 一共有四种安装工具 You have following opti ...

  6. CentOS 7.0 服务管理 – systemctl 命令

    转载自:http://linux.it.net.cn/CentOS/fast/2014/0720/3212.html CentOS 7.0中已经没有service命令,而是启用了systemctl服务 ...

  7. EF for oracle中无法读取配置 显示无法open问题解决方式

    1.更新以上设置为 非注销部分 弄了很久很久哈.

  8. fuser 和 lsof

    FUSER fuser功能fuser 可以显示出当前哪个程序在使用磁盘上的某个文件.挂载点.甚至网络端口,并给出程序进程的详细信息. fuser显示使用指定文件或者文件系统的进程ID.默认情况下每个文 ...

  9. openfire源码研究笔记:对设计模式及原则的学习

    原文:http://blog.csdn.net/jinzhencs/article/details/50522105 一.拦截器的实现 地点:   package org.jivesoftware.o ...

  10. setSystemUiVisibility() 与 getSystemUiVisibility() 显示隐藏状态栏

    Android  4.4  Camera 源码里面有一个操作界面的方法: /** * If {@param visible} is false, this hides the action bar a ...