例题: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;
}

  

最新文章

  1. Array常用方法
  2. ODBC简介
  3. JSP 内置对象(request response session application out pageContext)
  4. 【BZOJ】【1798】【AHOI2009】Seq维护序列
  5. javascript/jquery给动态加载的元素添加click事件
  6. Intel HEX file结构
  7. Java 的简单了解
  8. Android NDK 编译FFmpeg(不需要复杂的环境变量设置)
  9. character-RNN模型介绍以及代码解析
  10. not accessible due to restriction on required library
  11. wpa_supplicant_8_ti hostapd wpa_supplicant TI 官方的wpa_supplicant hostapd 移植到linux
  12. Flash对不同的浏览器的兼容性
  13. javascript 基本特性
  14. LeetCode刷题-004两个排序数组的中位数
  15. C语言--关于第0次作业
  16. 两台Linux机器传送文件
  17. mongodb副本集与分片结合
  18. 最优贸易 [NOIP 2009]
  19. Shell 变量、脚本参数
  20. [ 9.24 ]CF每日一题系列—— 468A构造递推

热门文章

  1. java面试题之什么是死锁、活锁、饿死和竞态条件?
  2. Controller配置汇总
  3. BZOJ——1606: [Usaco2008 Dec]Hay For Sale 购买干草
  4. 洛谷P1865 A % B Problem
  5. 33.JAVA编程思想——JAVA IO File类
  6. ubuntu uninstall postgres
  7. Android:图片中叠加文字,支持拖动改变位置
  8. 删除DataGridView选中行并更新数据库
  9. Multi-company rules
  10. TListView使用方法1(转)