http://poj.org/problem?id=2104 (题目链接)

题意

  求区间第k大数。

Solution1

  主席树裸题。

  主席树当时我学是学的要死,那个时候不晓得百度出什么bug了,搜个主席树出来的全是什么习主席巴拉巴拉的东西。。。于是找了个模板问同学自己磨出来的。

  有个博客我觉得写得还不错:想学主席树戳这里

  另外,这里的主席树储存的是值域,而不是别的。

代码

// poj2761
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define lim 1000000000
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=100010;
int n,m,sz,rt[maxn];
struct node {
int son[2],s;
int& operator [] (int x) {return son[x];}
}tr[maxn*40]; void build(int &u,int v,int l,int r,int val) {
u=++sz;
if (l==r) {tr[u].s=tr[v].s+1;return;}
int mid=(l+r)>>1;
if (val<=mid) build(tr[u][0],tr[v][0],l,mid,val),tr[u][1]=tr[v][1];
else build(tr[u][1],tr[v][1],mid+1,r,val),tr[u][0]=tr[v][0];
tr[u].s=tr[tr[u][0]].s+tr[tr[u][1]].s;
}
int query(int u,int v,int l,int r,int k) {
if (l==r) return l;
int mid=(l+r)>>1,c=tr[tr[v][0]].s-tr[tr[u][0]].s;
if (c>=k) return query(tr[u][0],tr[v][0],l,mid,k);
else return query(tr[u][1],tr[v][1],mid+1,r,k-c);
}
int main() {
scanf("%d%d",&n,&m);
for (int x,i=1;i<=n;i++) {
scanf("%d",&x);
build(rt[i],rt[i-1],-lim,lim,x);
}
for (int x,y,k,i=1;i<=m;i++) {
scanf("%d%d%d",&x,&y,&k);
printf("%d\n",query(rt[x-1],rt[y],-lim,lim,k));
}
return 0;
}

  


Solution2

  权值分块+莫队算法。

  好像静态的主席树都可以用 权值分块+莫队 解决,只是时间上和空间上有差异。这道题具体做法与bzoj2809差不多。

代码

// poj2104
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=100010;
struct ask {int l,r,k,id;}t[maxn];
struct data {int w,id;}a[maxn];
int pos[maxn],cnts[maxn],b[maxn],p[maxn],ma[maxn],ans[maxn],n,m,s,q,block; bool wcmp(data a,data b) {
return a.w<b.w;
}
bool poscmp(ask a,ask b) {
return pos[a.l]==pos[b.l] ? a.r<b.r : pos[a.l]<pos[b.l];
}
void build() {
block=(int)sqrt((float)m);
for (int i=1;i<=m;i++) pos[i]=(i-1)/block+1;
s=m%block ? m/block+1 : m/block;
for (int i=1;i<=s;i++) cnts[i]=0;
}
void update(int x,int val) {
cnts[pos[x]]+=val;
b[x]+=val;
}
int query(int k) {
int tot=0;
for (int i=1;i<=s;i++) {
tot+=cnts[i];
if (tot>=k) {
tot-=cnts[i];
for (int j=(i-1)*block+1;j<=min(i*block,m);j++) {
if (tot+b[j]>=k) return ma[j];
else tot+=b[j];
}
}
}
}
int main() {
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++) scanf("%d",&a[i].w),a[i].id=i;
for (int i=1;i<=q;i++) scanf("%d%d%d",&t[i].l,&t[i].r,&t[i].k),t[i].id=i;
sort(a+1,a+1+n,wcmp);
m=0;
ma[p[a[1].id]=++m]=a[1].w;
for (int i=2;i<=n;i++) {
if (a[i].w!=a[i-1].w) m++;
ma[p[a[i].id]=m]=a[i].w;
}
block=(int)sqrt((float)n);
for (int i=1;i<=n;i++) pos[i]=(i-1)/block+1;
sort(t+1,t+1+q,poscmp);
build();
for (int l=1,r=0,i=1;i<=q;i++) {
for (;r<t[i].r;r++) update(p[r+1],1);
for (;r>t[i].r;r--) update(p[r],-1);
for (;l<t[i].l;l++) update(p[l],-1);
for (;l>t[i].l;l--) update(p[l-1],1);
ans[t[i].id]=query(t[i].k);
}
for (int i=1;i<=q;i++) printf("%d\n",ans[i]);
return 0;
}

  

【bzoj2104】 K-th Number的更多相关文章

  1. 【CF245H】Queries for Number of Palindromes(回文树)

    [CF245H]Queries for Number of Palindromes(回文树) 题面 洛谷 题解 回文树,很类似原来一道后缀自动机的题目 后缀自动机那道题 看到\(n\)的范围很小,但是 ...

  2. 【转】oracle数据库NUMBER数据类型

    原文:http://www.jb51.net/article/37633.htm NUMBER ( precision, scale)a)  precision表示数字中的有效位;如果没有指定prec ...

  3. 【BZOJ3110】K大数查询(整体二分)

    [BZOJ3110]K大数查询(整体二分) 题面 BZOJ 题解 看了很久整体二分 一直不知道哪里写错了 ... 又把树状数组当成线段树区间加法来用了.. 整体二分还是要想清楚在干什么: 我们考虑第\ ...

  4. 【CF1133E】K Balanced Teams(动态规划,单调队列)

    [CF1133E]K Balanced Teams(动态规划,单调队列) 题面 CF 让你把一堆数选一些出来分成不超过\(K\)组,每一组里面的最大值和最小值之差不超过\(5\),求最多有多少个人元素 ...

  5. 【BZOJ4520】K远点对(KD-Tree)

    [BZOJ4520]K远点对(KD-Tree) 题面 BZOJ 洛谷 题解 考虑暴力. 维护一个大小为\(K\)的小根堆,然后每次把两个点之间的距离插进去,然后弹出堆顶 这样子可以用\(KD-Tree ...

  6. 【BZOJ4504】K个串 可持久化线段树+堆

    [BZOJ4504]K个串 Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计 ...

  7. 【BZOJ4026】dC Loves Number Theory 分解质因数+主席树

    [BZOJ4026]dC Loves Number Theory Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.    给 ...

  8. 【LeetCode】375. Guess Number Higher or Lower II 解题报告(Python)

    [LeetCode]375. Guess Number Higher or Lower II 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

  9. 【LeetCode】137. Single Number II 解题报告(Python)

    [LeetCode]137. Single Number II 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/single- ...

  10. 【LeetCode】306. Additive Number 解题报告(Python)

    [LeetCode]306. Additive Number 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http: ...

随机推荐

  1. Splay整理

    伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.(来自百科) 伸展树的操作主要是

  2. linux传输大文件

    http://dreamway.blog.51cto.com/1281816/1151886 linux传输大文件

  3. ZooKeeper 笔记(3) 实战应用之【统一配置管理】

    大型应用通常会按业务拆分成一个个业务子系统,这些大大小小的子应用,往往会使用一些公用的资源,比如:需要文件上传.下载时,各子应用都会访问公用的Ftp服务器.如果把Ftp Server的连接IP.端口号 ...

  4. c++游戏服务器编程学习笔记(一)TCP/IP

    1. c++游戏服务器编程c++运行效率非常高2. TCP传输控制协议IP网际协议Socket 3.Linux 乌班图开源第三方库BOOST 4.80%游戏服务器端用C++工作量最大的地方是具体的游戏 ...

  5. 如何用 fiddler 代理调试本地手机页面

    最近在做移动端的页面,但是移动端的调试很蛋疼.虽然说 90% 的功能都能用 chrome 下的模拟器来模拟解决,但是剩余的 10% 却只能在真机上调试.比如说一两个像素的误差,比如说只有真机上才能重现 ...

  6. .Net 异步方法加上“timeout”

    在本羊读大学的时候,Thread让本羊云里雾里,代码写的痛不欲生,真的是让本羊脑袋里很多“线”缠绕在一起. 之后,Task让本羊代码写的飞起,甚至有时候根本不需要Task的时候还是要写上,那样显得档次 ...

  7. Pathoto项目:AWS+golang+beego搭建

    帮兄弟写了一个网站,由于要在国外使用,选择了AWS作为服务器. 不知道后面的价格如何,12个月免费的确吸引了我. 花费3天时间,从注册到服务器搭建访问,终于搞定了.下面记录一下其中容易出错的命令. 1 ...

  8. 订餐系统之定时器Timer不定时

    经过几天漫长的问题分析.处理.测试.验证,定时器Timer终于定时了,于是开始了这篇文章,希望对还在纠结于“定时器Timer不定时”的同学有所帮助,现在的方案,在系统日志中会有警告,如果您有更好的方案 ...

  9. 前端 head 中mate 详解

    <meta name="viewport" content="width=device-width,height=device-height,initial-sca ...

  10. Bete冲刺第七阶段

    Bete冲刺第七阶段 今日工作: web: 新增通知处理接口 ios: 重写登录逻辑,添加创建行程填写.注册 POP界面 目前所遇问题: web: web目前进展顺利,暂时还没有遇到编码的问题. iO ...