描述

cjBBteam拥有一个很大的野生动物园。这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子。这些狮子从北到南编号为1,2,3,…,N。每头狮子都有一个觅食能力值Ai,Ai越小觅食能力越强。饲养员cmdButtons决定对狮子进行M次投喂,每次投喂都选择一个区间[I,J],从中选取觅食能力值第K强的狮子进行投喂。值得注意的是,cmdButtons不愿意对某些区域进行过多的投喂,他认为这样有悖公平。因此cmdButtons的投喂区间是互不包含的。你的任务就是算出每次投喂后,食物被哪头狮子吃掉了。

格式

输入格式

输入第一行有两个数N和M。此后一行有N个数,从南到北描述狮子的觅食能力值。此后M行,每行描述一次投喂。第t+2的三个数I,J,K表示在第t次投喂中,cmdButtons选择了区间[I,J]内觅食能力值第K强的狮子进行投喂。

输出格式

输出有M行,每行一个整数。第i行的整数表示在第i次投喂中吃到食物的狮子的觅食能力值。

样例1

样例输入1[复制]

7 2
1 5 2 6 3 7 4
1 5 3
2 7 1

样例输出1[复制]

3
2

限制

各个测试点2s

题意:没有修改,区间查询第k大

思路:裸的主席树。区间第K大及它的各类变种CLJ的《可持续化数据结构研究》分析地很详细了 orz

/** @Date    : 2016-12-15-20.55
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version :
*/
#include<bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8; struct yuu
{
int a, b, sum;
int l, r;
}tt[N << 5]; int n, m;
int rt[N], a[N], ss[N];
int cnt; void build(int a, int b, int &p)
{
p = ++cnt;
tt[p].a = a;
tt[p].b = b;
if(a == b)
return ;
int mid = (a + b) >> 1;
build(a, mid, tt[p].l);
build(mid + 1, b, tt[p].r);
} void add(int pre, int &p, int pos)
{
p = ++cnt;
tt[p].l = tt[pre].l;
tt[p].r = tt[pre].r;
tt[p].a = tt[pre].a;
tt[p].b = tt[pre].b;
tt[p].sum = tt[pre].sum + 1;
int mid = (tt[pre].a + tt[pre].b) >> 1;
if(tt[pre].a < tt[pre].b)
if(pos <= mid)
add(tt[pre].l, tt[p].l, pos);
else add(tt[pre].r, tt[p].r, pos);
} int query(int pre, int nw, int s)
{
if(tt[nw].a == tt[nw].b)
{
return ss[tt[nw].a];
} int t = tt[tt[nw].l].sum - tt[tt[pre].l].sum; if(s <= t)
return query(tt[pre].l, tt[nw].l, s);
else
return query(tt[pre].r, tt[nw].r, s - t);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]), ss[i] = a[i];
sort(ss + 1, ss + 1 + n);
MMF(rt);
cnt = 0;
build(1, n, rt[0]);
for(int i = 1; i <= n; i++)
{
int pos = lower_bound(ss + 1, ss + 1 + n, a[i]) - ss;
add(rt[i - 1], rt[i], pos);
}
for(int i = 1; i <= m; i++)
{
int x, y, k;
scanf("%d%d%d", &x, &y, &k);
int ans = query(rt[x - 1], rt[y], k);
printf("%d\n", ans);
}
return 0;
}

vijos 1081 野生动物园 函数式线段树的更多相关文章

  1. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  2. POJ2104 K-th number 函数式线段树

    很久没打代码了,不知道为什么,昨天考岭南文化之前突然开始思考起这个问题来,这个问题据说有很多种方法,划分树什么的,不过对于我现在这种水平还是用熟悉的线段树做比较好.这到题今年8月份的时候曾经做过,那个 ...

  3. BZOJ 3123 森林(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3123 题意: 思路:总的来说,查询区间第K小利用函数式线段树的减法操作.对于两棵树的合并 ...

  4. BZOJ 3207 花神的嘲讽计划Ⅰ(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3207 题意:给出一个数列,若干询问.每个询问查询[L,R]区间内是否存在某个长度为K的子 ...

  5. [Usaco2014 Open Gold ]Cow Optics (树状数组+扫描线/函数式线段树)

    这道题一上手就知道怎么做了= = 直接求出原光路和从目标点出发的光路,求这些光路的交点就行了 然后用树状数组+扫描线或函数式线段树就能过了= = 大量的离散+模拟+二分什么的特别恶心,考试的时候是想到 ...

  6. hdu 5111 树链剖分加函数式线段树

    这题说的是给了两棵树,各有100000 个节点,然后Q个操作Q<=50000; 每个操作L1 R1 L2 R2.因为对于每棵树都有一个与本棵树其他点与众不同的值, 最后问 在树上从L1到R1这条 ...

  7. Codeforces538F A Heap of Heaps(函数式线段树)

    题意:给你一个数组a[n],对于数组每次建立一个完全k叉树,对于每个节点,如果父节点的值比这个节点的值大,那么就是一个违规点,统计出1~n-1完全叉树下的违规点的各自的个数. 一个直觉的思想就是暴力, ...

  8. VIJOS P1081 野生动物园 SBT、划分树模板

    [描述] cjBBteam拥有一个很大的野生动物园.这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子.这些狮子从北到南编号为1,2,3,…,N.每头狮子都有 ...

  9. Vijos 1083 小白逛公园(线段树)

    线段树,每个结点维护区间内的最大值M,和sum,最大前缀和lm,最大后缀和rm. 若要求区间为[a,b],则答案max(此区间M,左儿子M,右儿子M,左儿子rm+右儿子lm). ----------- ...

随机推荐

  1. 有道云笔记Markdown使用

    目录 使用规则 代码高亮 制作待办事项 高效绘图 基本规则 使用规则 代码高亮 #include <iostream> #include <string> using name ...

  2. POJ 2826 An Easy Problem?!(线段交点+简单计算)

    Description It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Be ...

  3. 常用linux命令相关

    [查看端口] netstat -tlnp netstat命令 netstat -an | grep 3306 3306替换成需要grep的端口号 lsof命令 通过list open file命令可以 ...

  4. Python为什么会打印两个\

    在Python里面,如果\后面不是一个合法的转移字符,那么,Python会打印两个\,换句话说,Python将\也当成普通字符看待,而不是转义符的标志: >>>S = 'C:\py\ ...

  5. 常用算法Java实现之直接插入排序

    直接插入排序是将未排序的数据插入至已排好序序列的合适位置. 具体流程如下: 1.首先比较数组的前两个数据,并排序: 2.比较第三个元素与前两个排好序的数据,并将第三个元素放入适当的位置: 3.比较第四 ...

  6. redis——持久化方式RDB与AOF分析

    https://blog.csdn.net/u014229282/article/details/81121214 redis两种持久化的方式 RDB持久化可以在指定的时间间隔内生成数据集的时间点快照 ...

  7. 《Effective C#》快速笔记(四)- 使用框架

    .NET 是一个类库,你了解的越多,自己需要编写的代码就越少. 目录 三十.使用重写而不是事件处理函数 三十一.使用 IComparable<T> 和 IComparer<T> ...

  8. [计算机网络-应用层] HTTP协议

    1.HTTP概况 Web的应用层协议是超文本传输协议(HTTP),它是Web的核心. HTTP由两部分程序实现:一个客户机程序和一个服务器程序,它们运行在不同的端系统中,通过交换HTTP报文进行对话. ...

  9. 2011 Multi-University Training Contest 4 - Host by SDU

    A.Color the Simple Cycle(polya计数+字符串匹配) 此题的难点在于确定置换的个数,由a[i+k]=a[i], e[i+k]=e[i]联想到KMP. 于是把原串和原串扩大两倍 ...

  10. Luogu3936 Coloring(模拟退火)

    裸退火,每次交换两个格子即可.依旧不会调参,稍微抄了点参数并且把随机种子设成了一个神奇的数字终于过掉了. #include<iostream> #include<cstdio> ...