poj2104 划分树
2013-07-30 10:24
197 查看
划分树模板题,第一次写,昨天晚上琢磨了一晚上把思路理清楚,早上起来Wrong了之后,检查出一个下标错误,险险的A掉了。
ACcode:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int NS=100010;
struct node{
int num[NS];
int val[NS];
}row[18];
LL tot;
int n,m;
int st[NS];
void build(int dep,int L,int R)
{
if (L==R) return ;
int mid=(L+R)>>1;
int same=mid-L+1;
int idl=L,idr=mid+1;
for (int i=L;i<=R;i++)
if (row[dep].val[i]<st[mid]) same--;
for (int i=L;i<=R;i++)
{
if (i==L)
row[dep].num[i]=0;
else
row[dep].num[i]=row[dep].num[i-1];
if (row[dep].val[i]<st[mid]) {
row[dep].num[i]++;
row[dep+1].val[idl++]=row[dep].val[i];
} else if (row[dep].val[i]>st[mid]) {
row[dep+1].val[idr++]=row[dep].val[i];
} else {
if (same>0){
same--;
row[dep].num[i]++;
row[dep+1].val[idl++]=row[dep].val[i];
} else {
row[dep+1].val[idr++]=row[dep].val[i];
}
}
}
build(dep+1,L,mid);
build(dep+1,mid+1,R);
}
int query(int dep,int k,int x,int y,int L,int R)
{
if (L==R) return row[dep].val[L];
int a,b,ctl,ctm,sxy;
int mid=(L+R)>>1;
if (x==L)
ctl=0;
else
ctl=row[dep].num[x-1];
ctm=row[dep].num[y]-ctl;
if (ctm>=k) {
a=L+ctl;
b=a+ctm-1;
R=mid;
} else {
a=mid+1+(x-L-ctl);
b=a+(y-x+1-ctm)-1;
L=mid+1;
k-=ctm;
}
return query(dep+1,k,a,b,L,R);
}
int main()
{
int x,y,k;
while (~scanf("%d %d",&n,&m))
{
for (int i=1;i<=n;i++)
{
scanf("%d",&st[i]);
row[0].val[i]=st[i];
}
sort(st+1,st+n+1);
build(0,1,n);
while (m--)
{
scanf("%d %d %d",&x,&y,&k),tot=0;
printf("%d\n",query(0,k,x,y,1,n));
}
}
return 0;
}
ACcode:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int NS=100010;
struct node{
int num[NS];
int val[NS];
}row[18];
LL tot;
int n,m;
int st[NS];
void build(int dep,int L,int R)
{
if (L==R) return ;
int mid=(L+R)>>1;
int same=mid-L+1;
int idl=L,idr=mid+1;
for (int i=L;i<=R;i++)
if (row[dep].val[i]<st[mid]) same--;
for (int i=L;i<=R;i++)
{
if (i==L)
row[dep].num[i]=0;
else
row[dep].num[i]=row[dep].num[i-1];
if (row[dep].val[i]<st[mid]) {
row[dep].num[i]++;
row[dep+1].val[idl++]=row[dep].val[i];
} else if (row[dep].val[i]>st[mid]) {
row[dep+1].val[idr++]=row[dep].val[i];
} else {
if (same>0){
same--;
row[dep].num[i]++;
row[dep+1].val[idl++]=row[dep].val[i];
} else {
row[dep+1].val[idr++]=row[dep].val[i];
}
}
}
build(dep+1,L,mid);
build(dep+1,mid+1,R);
}
int query(int dep,int k,int x,int y,int L,int R)
{
if (L==R) return row[dep].val[L];
int a,b,ctl,ctm,sxy;
int mid=(L+R)>>1;
if (x==L)
ctl=0;
else
ctl=row[dep].num[x-1];
ctm=row[dep].num[y]-ctl;
if (ctm>=k) {
a=L+ctl;
b=a+ctm-1;
R=mid;
} else {
a=mid+1+(x-L-ctl);
b=a+(y-x+1-ctm)-1;
L=mid+1;
k-=ctm;
}
return query(dep+1,k,a,b,L,R);
}
int main()
{
int x,y,k;
while (~scanf("%d %d",&n,&m))
{
for (int i=1;i<=n;i++)
{
scanf("%d",&st[i]);
row[0].val[i]=st[i];
}
sort(st+1,st+n+1);
build(0,1,n);
while (m--)
{
scanf("%d %d %d",&x,&y,&k),tot=0;
printf("%d\n",query(0,k,x,y,1,n));
}
}
return 0;
}
相关文章推荐
- poj2104 划分树 区间K大 在线 无修改
- 查询区间第k大 POJ2104 暴力 or 划分树 or 归并树
- 划分树的用法(一):查询区间第K大值值(poj2104)
- 划分树的用法(一):查询区间第K大值值(poj2104)
- 划分树 poj2104 hdu5249
- poj2104 求区间第k大数(划分&&主席--待补)
- POJ2104 K-th Number(划分树和主席树代码)
- POJ2104:划分树求区间第k小
- 划分树-POJ2104,POJ2761,HDU2665,HDU3743
- POJ2104 POJ2761 K-th Number, 划分树
- poj2104[划分树问题]
- 划分树的用法(一):查询区间第K大值值(poj2104)
- POJ2104 k-th number 划分树
- 整数划分
- 思科VLAN划分经典案例
- 【算法学习笔记】21.算法设计初步 求第k个数 划分法 快排法
- 证明两个集合的划分最小绝对值差问题
- SDUT3146:Integer division 2(整数划分区间dp)
- 快速排序(2)算法改进--小的子文件、三者取中、重复关键字三路划分
- 等价类的划分方法与EditorBox问题等价类划分