例题:poj2761

题目要求:给定一个长度为n的序列,给定m个询问,每次询问求[l,r]区间内的第k大;

对于这道题目来说,很多算法都可以使用,比如说树套树(一个负责划分区间,一个负责维护这段区间内的信息),主席树等;

对这道题我使用的是主席树;

主席树对付区间第k大是很优秀的,代码短,而且常数小;

主席树的主要功能是,建立n颗范围是1-i的权值线段树,对两颗线段树做差,就可以任意一个区间内的权值线段树;

详细看代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iomanip>
#include<stack>
using namespace std;
#define FILE "dealing"
#define up(i,j,n) for(int i=(j);i<=(n);i++)
#define pii pair<int,int>
#define LL int
#define mem(f,g) memset(f,g,sizeof(f))
namespace IO{
char buf[1<<15],*fs,*ft;
int gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?-1:*fs++;}
int read(){
int ch=gc(),f=0,x=0;
while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=gc();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}
return f?-x:x;
}
int readint(){
int ch=getchar(),f=0,x=0;
while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?-x:x;
}
}using namespace IO;
const int maxn=101000<<5,inf=1000000000;
int n,m,c[maxn];
struct node{
int k,id;
bool operator<(const node b)const{return k<b.k;}
}a[maxn];
namespace chair_tree{
int c[maxn][2],sum[maxn],cnt=0,rt[maxn],d;
#define mid ((l+r)>>1)
void updata(int o){sum[o]=sum[c[o][0]]+sum[c[o][1]];}
void insert(int key,int pre,int& o,int l,int r){
if(!o)o=++cnt;
if(l==r){sum[o]=1;return;}
d=key>mid;
c[o][d^1]=c[pre][d^1];
insert(key,c[pre][d],c[o][d],d?mid+1:l,d?r:mid);
updata(o);
}
void init(int *a,int n){up(i,1,n)insert(a[i],rt[i-1],rt[i],1,n);}
int query(int l,int r,int x,int y,int k){
if(l==r)return l;
d=sum[c[y][0]]-sum[c[x][0]];
if(k<d)return query(l,mid,c[x][0],c[y][0],k);
else return query(mid+1,r,c[x][1],c[y][1],k-d);
}
int Query(int l,int r,int k){return query(1,n,rt[l-1],rt[r],k-1);}
};
int main(){
n=read(),m=read();
up(i,1,n)a[i].k=read(),a[i].id=i;
sort(a+1,a+n+1);
up(i,1,n)c[a[i].id]=i;
chair_tree::init(c,n);
int l,r,k;
int pre=0,q=(1<<8)-1;
while(m--){
l=read(),r=read(),k=read();
l^=(pre&q),r^=(pre&q);
if(!l)l=1;if(!r)r=1;
if(l>r)swap(l,r);
printf("%d\n",pre=a[chair_tree::Query(l,r,k)].k);
}
return 0;
}

  

poj2761静态区间第k大的更多相关文章

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

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

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

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

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

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

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

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

  5. 可持久化线段树(主席树)——静态区间第k大

    主席树基本操作:静态区间第k大 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=2e5+, ...

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

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

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

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

  8. POJ2104-- K-th Number(主席树静态区间第k大)

    [转载]一篇还算可以的文章,关于可持久化线段树http://finaltheory.info/?p=249 无修改的区间第K大 我们先考虑简化的问题:我们要询问整个区间内的第K大.这样我们对值域建线段 ...

  9. HDU 2665 Kth number(主席树静态区间第K大)题解

    题意:问你区间第k大是谁 思路:主席树就是可持久化线段树,他是由多个历史版本的权值线段树(不是普通线段树)组成的. 具体可以看q学姐的B站视频 代码: #include<cmath> #i ...

随机推荐

  1. eclipse导入svn检出的maven项目问题

    1.修改项目jdk环境和编译环境.消除红叉. 2.windows-preferences-java-installed jres,修改工作空间的jdk,在Default vm arguments栏中添 ...

  2. Spoj-BOKAM143SOU Checking cubes.

    Given a integer N. Find number of possible ways to represent N as a sum of at most five cubes. Input ...

  3. android图片上传

    package com.example.center; import java.io.ByteArrayOutputStream;import java.io.InputStream; import ...

  4. mysql date_add日期函数的使用

    select date_add(CURRENT_DATE()-day(CURRENT_DATE())+1,interval 3 month);##my sql 获取三个月之后的第一天日期select  ...

  5. 生成PDF文档

    byte[] buffer = context.Response.Clear(); context.Response.ClearHeaders(); context.Response.ClearCon ...

  6. 一点点VIM

    VIM 当你喜欢它时,你会发现真的不错,不过配置真是麻烦, 不过万事开头难,当你熟练时真的会发现她的美. syntax on set nu colo evening set mouse=a set c ...

  7. 51 NOD 1406 and query

    我们知道一个数S会对所有它的子集S'产生1的贡献,但是我们直接枚举子集是 3^(log2 1000000)的,会炸掉:如果直接把每个有1的位变成0往下推也会凉掉,因为这样会有很多重复的. 但是我们发现 ...

  8. BUPT复试专题—找最小数(2010)

    https://www.nowcoder.com/practice/ba91786c4759403992896d859e87a6cd?tpId=67&tqId=29645&rp=0&a ...

  9. "听话"的品格的症状

    反思了一下,也许是因为以前比较听话,听大人的话,听老师的话,听长辈的话.听电视剧的话..........哈哈 现在发现,世界是靠自己去认识,去体会的,别人的经验都只能作为参考,绝对不能不加思考的照搬硬 ...

  10. JavaSE Map的使用

    1.Map概述 Map与Collection并列存在.用来保存具有映射关系的数据:Key-Value Map 中的 key 和  value都能够是不论什么引用类型的数据 Map 中的 key 用Se ...