话说本周日就要本人的第一场现场赛了,求RP。。。
刚刚把划分树的模板题搞掂了,从了解划分树的原理,到阅读神牛的模板,再到自己写模板,还是不轻松的。。。
http://blog.csdn.net/zxy_snow/article/details/6681086
这位MM的解释还是灰常清楚地,原理在这我就不多说了,下面帖我的代码,其实大同小异。。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define lson(rt) rt<<1
#define rson(rt) rt<<1|1
#define cl(a) memset(a,0,sizeof(a))
#define ss(a) scanf("%d",&a)
using namespace std;
const int N=100100;
struct seg_tree
{
int left;
int right;
int midd()
{
return (left+right)>>1;
}
}tree[N<<3];
int val[20][N],toleft[20][N],a[N];
void build(int l,int r,int d,int rt)
{
int i;
tree[rt].left=l;
tree[rt].right=r;
if (l==r) return;
int mid=tree[rt].midd();
int lsame=mid-l+1,same=0;
for (i=l;i<=r;i++)
if (val[d][i]<a[mid]) lsame--;
int lpos=l,rpos=mid+1;
for (i=l;i<=r;i++)
{
int x=val[d][i];
if (i==l) toleft[d][i]=0;
else toleft[d][i]=toleft[d][i-1];
if (val[d][i]<a[mid])
{
toleft[d][i]++;
val[d+1][lpos++]=x;
}
else if (val[d][i]>a[mid])
{
val[d+1][rpos++]=x;
}
else if (same<lsame)
{
same++;
toleft[d][i]++;
val[d+1][lpos++]=x;
}
else val[d+1][rpos++]=x;
}
build(l,mid,d+1,lson(rt));
build(mid+1,r,d+1,rson(rt));
}
int query(int k,int l,int r,int d,int rt)
{
if (l==r) return val[d][l];
int s,ss,mid,le,newl,newr;
mid=tree[rt].midd();
le=tree[rt].left;
if (l==le)
{
ss=0;
s=toleft[d][r];
}
else
{
ss=toleft[d][l-1];
s=toleft[d][r]-toleft[d][l-1];
}
if (s>=k)
{
newl=le+ss;
newr=le+ss+s-1;
return query(k,newl,newr,d+1,lson(rt));
}
else
{
int bb=l-le-ss;
int b=r-l+1-s;
newl=mid+bb+1;
newr=mid+bb+b;
return query(k-s,newl,newr,d+1,rson(rt));
}
}
int main()
{
int n,m,i;
while (ss(n)!=EOF)
{
ss(m);
cl(a);cl(val);cl(toleft);
for (i=1;i<=n;i++)
{
ss(a[i]);
val[0][i]=a[i];
}
sort(a,a+n+1);
build(1,n,0,1);
for (i=1;i<=m;i++)
{
int le,ri,k;
ss(le);ss(ri);ss(k);
int res=query(k,le,ri,0,1);
printf("%d\n",res);
}
}
return 0;
}