POJ 2104/HDU 2665 区间k大值 函数式线段树
ORZ主席,这可持久化数据结构真是碉堡了!~
PS:这两个题的读入是不同的。。。
View Code
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 7 #define N 100010 8 9 using namespace std; 10 11 int h[N<<5],ls[N<<5],rs[N<<5],sum[N<<5]; 12 int cnt,n,m; 13 int a[N],bh[N]; 14 15 inline int newnode(int s,int l,int r) 16 { 17 ++cnt; 18 sum[cnt]=s; ls[cnt]=l; rs[cnt]=r; 19 return cnt; 20 } 21 22 inline void build(int l,int r,int &rt) 23 { 24 rt=newnode(0,0,0); 25 if(l==r) return; 26 int mid=(l+r)>>1; 27 build(l,mid,ls[rt]); 28 build(mid+1,r,rs[rt]); 29 } 30 31 inline void updata(int last,int pos,int l,int r,int &rt) 32 { 33 rt=newnode(sum[last]+1,ls[last],rs[last]); 34 if(l==r) return; 35 int mid=(l+r)>>1; 36 if(pos<=mid) updata(ls[last],pos,l,mid,ls[rt]); 37 else updata(rs[last],pos,mid+1,r,rs[rt]); 38 } 39 40 inline int query(int st,int ed,int l,int r,int k) 41 { 42 if(l==r) return l; 43 int mid=(l+r)>>1; 44 int tmp=sum[ls[ed]]-sum[ls[st]]; 45 if(k<=tmp) return query(ls[st],ls[ed],l,mid,k); 46 else return query(rs[st],rs[ed],mid+1,r,k-tmp); 47 } 48 49 inline void read() 50 { 51 cnt=0; 52 for(int i=1;i<=n;i++) 53 { 54 scanf("%d",&a[i]); 55 bh[i]=a[i]; 56 } 57 } 58 59 inline void go() 60 { 61 sort(bh+1,bh+1+n); 62 int num=unique(bh+1,bh+1+n)-bh-1; 63 for(int i=1;i<=n;i++) a[i]=lower_bound(bh+1,bh+1+num,a[i])-bh; 64 build(1,num,h[0]); 65 for(int i=1;i<=n;i++) updata(h[i-1],a[i],1,num,h[i]); 66 int l,r,k; 67 while(m--) 68 { 69 scanf("%d%d%d",&l,&r,&k); 70 printf("%d\n",bh[query(h[l-1],h[r],1,num,k)]); 71 } 72 } 73 74 int main() 75 { 76 while(scanf("%d%d",&n,&m)!=EOF) read(),go(); 77 return 0; 78 }
没有人能阻止我前进的步伐,除了我自己!