博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2104(K-th Number-区间第k大-主席树)
阅读量:7222 次
发布时间:2019-06-29

本文共 4876 字,大约阅读时间需要 16 分钟。

 

K-th Number
Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 31790   Accepted: 9838
Case Time Limit: 2000MS

Description

You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. 
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?" 
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.

Input

The first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000). 
The second line contains n different integer numbers not exceeding 10
9 by their absolute values --- the array for which the answers should be given. 
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).

Output

For each question output the answer to it --- the k-th number in sorted a[i...j] segment.

Sample Input

7 31 5 2 6 3 7 42 5 34 4 11 7 3

Sample Output

563

Hint

This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.

Source

, Northern Subregion

 

这题是主席树裸题。

但是我却狂T——

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Rep(i,n) for(int i=0;i
=0;i--)#define MAXN (100000+10)#define MAXM (5000+10)int n,m,a[MAXN],a2[MAXN];struct node{ node *ch[2]; int a,siz; node(){ch[0]=ch[1]=NULL;siz=a=0;} node(node *_ch0,node *_ch1,int _a,int _siz):a(_a),siz(_siz){ch[0]=_ch0,ch[1]=_ch1;} void update() { siz=a; if (ch[0]) siz+=ch[0]->siz; if (ch[1]) siz+=ch[1]->siz; }}*null=new node(),*root[MAXN]={NULL};void make_node(node *&y,node *&x,int l,int r,int t){ if (x==NULL) x=null; y=new node(); int m=(l+r)>>1; if (l==r) { *y=*x; y->siz++;y->a++; return; } if (t<=a2[m]) { make_node(y->ch[0],x->ch[0],l,m,t); y->ch[1]=x->ch[1]; y->update(); } else { make_node(y->ch[1],x->ch[1],m+1,r,t); y->ch[0]=x->ch[0]; y->update(); }}void find(node *&x1,node *&x2,int l,int r,int k){ if (x1==NULL) x1=null; if (x2==NULL) x2=null; if (l==r) {printf("%d\n",a2[l]);return;} int m=(l+r)>>1; int ls=0; if (x2->ch[0]) ls+=x2->ch[0]->siz; if (x1->ch[0]) ls-=x1->ch[0]->siz; if (ls>=k) find(x1->ch[0],x2->ch[0],l,m,k); else find(x1->ch[1],x2->ch[1],m+1,r,k-ls);}int main(){ freopen("poj2104.in","r",stdin); null->ch[0]=null; null->ch[1]=null; scanf("%d%d",&n,&m); For(i,n) scanf("%d",&a[i]),a2[i]=a[i]; sort(a2+1,a2+1+n); int size=unique(a2+1,a2+1+n)-(a2+1); For(i,n) { make_node(root[i],root[i-1],1,size,a[i]); } For(i,m) { int l,r,k; scanf("%d%d%d",&l,&r,&k); find(root[l-1],root[r],1,size,k); } return 0;}

于是在柯老师的教导下,我发现致使我狂T的因素是不断new 结点,于是我将结点事先用数组开好。

 

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Rep(i,n) for(int i=0;i
=0;i--)#define MAXN (200000+10)#define MAXM (200000+10)int n,m,a[MAXN],a2[MAXN];struct node{ node *ch[2]; int a,siz; node(){ch[0]=ch[1]=NULL;siz=a=0;} void update() { siz=a; if (ch[0]) siz+=ch[0]->siz; if (ch[1]) siz+=ch[1]->siz; }}*null=new node(),*root[MAXN]={NULL},q[MAXN*9];int q_s;void make_node(node *&y,node *&x,int l,int r,int t){ if (x==NULL) x=null; y=&q[++q_s]; *y=node(); int m=(l+r)>>1; if (l==r) { *y=*x; y->siz++;y->a++; return; } if (t<=a2[m]) { make_node(y->ch[0],x->ch[0],l,m,t); y->ch[1]=x->ch[1]; y->update(); } else { make_node(y->ch[1],x->ch[1],m+1,r,t); y->ch[0]=x->ch[0]; y->update(); }}void find(node *&x1,node *&x2,int l,int r,int k){ if (x1==NULL) x1=null; if (x2==NULL) x2=null; if (l==r) {printf("%d\n",a2[l]);return;} int m=(l+r)>>1; int ls=0; if (x2->ch[0]) ls+=x2->ch[0]->siz; if (x1->ch[0]) ls-=x1->ch[0]->siz; if (ls>=k) find(x1->ch[0],x2->ch[0],l,m,k); else find(x1->ch[1],x2->ch[1],m+1,r,k-ls);}int main(){ //freopen("hdu2665.in","r",stdin); null->ch[0]=null; null->ch[1]=null; q_s=0; scanf("%d%d",&n,&m); For(i,n) scanf("%d",&a[i]),a2[i]=a[i]; sort(a2+1,a2+1+n); int size=unique(a2+1,a2+1+n)-(a2+1); For(i,n) { make_node(root[i],root[i-1],1,size,a[i]); } For(i,m) { int l,r,k; scanf("%d%d%d",&l,&r,&k); find(root[l-1],root[r],1,size,k); } return 0;}

终于过了……伤不起……

 

 

转载地址:http://zchym.baihongyu.com/

你可能感兴趣的文章
WPF Step By Step 系列-Prism框架在项目中使用
查看>>
rdesktop:Linux 下的远程桌面客户端[转]
查看>>
「Linux」Ubuntu12.10 64位安装虚拟机打开失败的解决办法
查看>>
XCode 4.5安装与运行条件
查看>>
知乎上,月薪超过 1 万元的人士从事的是什么工作? - 知乎
查看>>
Java生成验证码
查看>>
深度解析windows调试技术之一 [抓取user mode dump文件的几重境界]
查看>>
Codeforces Round #168 (Div. 2) A. Lights Out(模拟)
查看>>
免费素材: Retina Glyph图标集 (包含100个AI & PNG格式的图标)
查看>>
阳历转阴历算法概述
查看>>
深入浅出事件流处理NEsper(一)
查看>>
ALTER FPGA通过软件设置上拉(转)
查看>>
Chronon 3.5 发布,支持 Java 7
查看>>
关于Windows内存的一些参考文章
查看>>
WCF Concurrency (Single, Multiple, and Reentrant) and Throttling
查看>>
构建高性能的ASP.NET应用(二)-性能优化演绎法
查看>>
CentOS6.2安装Oracle Oracle Net Configuration Assistant failed 错误
查看>>
经济泡沫破灭后,那些人的日子会比较难过?
查看>>
[转载]PostgreSQL学习手册(目录)
查看>>
SIGTERM等信号含义
查看>>