http://poj.org/problem?id=2104

题意:
求区间$[l,r]$的第k小。

思路:
主席树不好理解啊,简单叙述一下吧。

主席树就是由多棵线段树组成的,对于数组$a[1,2...n]$,对于每个i,我们都去建立一棵线段树维护$a[1,..i]$出现的数的个数。

但是如果每一棵线段树都去新建结点的话,那这内存的开销是十分巨大的。。。

我们可以发现,第i棵线段树和第i-1棵线段树有很多结点都是相同的,这样一来,我们就没必要再去重新新建结点了,直接套用上一棵线段树的结点即可。

这里我想引用一张某大神博客的手绘图解:(来自http://blog.csdn.net/regina8023/article/details/41910615

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m;
int tot_num;
int tot=;
int b[maxn],c[maxn],t[maxn]; struct node
{
int l,r,num;
}a[maxn*]; int build(int l ,int r)
{
int root=++tot;
a[root].num=;
if(l==r) return root;
int mid=(l+r)>>;
a[root].l=build(l,mid);
a[root].r=build(mid+,r);
return root;
} int update(int root, int x)
{
int now=++tot;
int tmp=now;
a[tot].num=a[root].num+;
int l=,r=tot_num;
while(l<r)
{
int mid=(l+r)>>;
if(x<=mid)
{
a[now].l=++tot;
a[now].r=a[root].r; //这儿不需修改,套用上一棵线段树的数即可
root=a[root].l;
now=tot;
r=mid;
}
else
{
a[now].l=a[root].l; //同理
a[now].r=++tot;
root=a[root].r;
now=tot;
l=mid+;
}
a[now].num=a[root].num+;
}
return tmp;
} int query(int ql, int qr, int k)
{
int l=,r=tot_num;
while (l<r)
{
int mid=(l+r)>>;
if (a[a[qr].l].num-a[a[ql].l].num>=k) //>=k,说明肯定在该区间内,继续往下缩小范围
{
r=mid;
ql=a[ql].l;
qr=a[qr].l;
}
else
{
l=mid+;
k-=a[a[qr].l].num-a[a[ql].l].num; //<k,说明左区间的数不够,先减去左区间的数,然后往右区间搜索
ql=a[ql].r;
qr=a[qr].r;
}
}
return l;
} int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&c[i]);
b[i]=c[i];
}
sort(b+,b+n+);
tot_num=unique(b+,b+n+)-b-;
t[]=build(,tot_num); //初始化
for(int i=;i<=n;i++)
{
t[i]=update(t[i-],lower_bound(b+,b+tot_num+,c[i])-b);
}
while(m--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",b[query(t[l-],t[r],k)]);
}
return ;
}

POJ 2104 K-th Number(主席树模板题)的更多相关文章

  1. 【POJ 2104】 K-th Number 主席树模板题

    达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...

  2. 主席树:POJ2104 K-th Number (主席树模板题)

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

  3. SPOJ MKTHNUM & POJ 2104 - K-th Number - [主席树模板题]

    题目链接:http://poj.org/problem?id=2104 Description You are working for Macrohard company in data struct ...

  4. 【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题

    达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360 说一下我对这个模板的理解: 看到这个方法很容易不知所措,因为动态K值需要套树状 ...

  5. poj2104 主席树模板题

    题意 给出n个数字组成的数字序列,有m组询问.每次询问包含三个数字l,r,k.对于每个询问输出序列区间[l,r]中第k大的数字. 分析 这是主席树的模板题,套板子就可以 #include <cs ...

  6. hdu2665(主席树模板题)

    hdu2665 题意 求区间第 k 小. 分析 参考 这类题目做法挺多的,例如 划分树. 这里使用主席树再写一发,不得不说主席树相比而言要好写的多,比起普通线段树,主席树就是复用了线段树共有的信息. ...

  7. POJ-2104-K-th Number(区间第K大+主席树模板题)

    Description You are working for Macrohard company in data structures department. After failing your ...

  8. POJ 2104 主席树模板题

    #include <iostream> #include <cstdio> #include <algorithm> int const maxn = 200010 ...

  9. POJ2104 K-th Number 划分树 模板题啊

    /*Source Code Problem: 2104 User: 96655 Memory: 14808K Time: 1282MS Language: G++ Result: Accepted S ...

随机推荐

  1. 10 ref 和 out 之间的差别

    (1) 两者都是按地址传递的,使用后都将改变原来的数值 (2) ref传进去的參数必须在调用前初始化,out不必 (3) ref传进去的參数在函数内部能够直接使用,而out不可 (4) ref传进去的 ...

  2. Selenium定位元素-Xpath的使用方法

    工具 Xpath的练习建议下载火狐浏览器,下载插件Firebug.Firepath. 由于最新版火狐不支持Firebug等扩展工具了,所以需要下载49版以下的版本安装https://ftp.mozil ...

  3. c#实现图片二值化例子(黑白效果)

    C#将图片2值化示例代码,原图及二值化后的图片如下: 原图: 二值化后的图像: 实现代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...

  4. Android中Activity的四种开发模式

    Activity的四种启动模式:standard.singleTop.singleTask.singleInstance   清单文件中的Activity配置使用:android:launchMode ...

  5. scipy模块

  6. linux cut字符串切割

    linux字符串列截取  cut  -d ‘分割条件’ -f ‘列数’ [root@LocalWeb01 ~]# less  /etc/passwd | grep '^user' | grep -v ...

  7. python start

    由于工作关系,新学习使用了python,感觉能非常快速和方便的开发,看完<简明 Python 教程>就跃跃欲试,实际用的是发现有些和C#的理解不一样 (1)如何筛选元组 例如  recor ...

  8. Junit4用法

    序号 方法和描述 1 void assertEquals(boolean expected, boolean actual) 检查两个变量或者等式是否平衡 2 void assertTrue(bool ...

  9. 利用keyframes实现幻灯效果

    源码如下: <style> @keyframes looppic{ from{ background:url(images/1.jpg); /*图片的地址*/ } 25%{ /*可以依据不 ...

  10. ACM数论之旅10---大组合数-卢卡斯定理(在下卢卡斯,你是我的Master吗?(。-`ω´-) )

    记得前几章的组合数吧 我们学了O(n^2)的做法,加上逆元,我们又会了O(n)的做法 现在来了新问题,如果n和m很大呢, 比如求C(n, m) % p  , n<=1e18,m<=1e18 ...