poj 2182
线段树代码:
(1.普通二叉树,0ms)
#include<stdio.h>
struct {
int l,r,len;
}tree[8005<<2];
int pre[8005],ans[8005];
void buildtree(int left,int right,int u) {
tree[u].l=left;
tree[u].r=right;
tree[u].len=right-left+1;
if(left==right) return;
buildtree(left,left+right>>1,u<<1);
buildtree((left+right>>1)+1,right,(u<<1)+1);
}
int query(int u,int num) {
--tree[u].len;
if(tree[u].l==tree[u].r) return tree[u].l;
if(tree[u<<1].len<num) return query((u<<1)+1,num-tree[u<<1].len);
else return query(u<<1,num);
}
int main() {
int n;
scanf("%d",&n);
pre[1]=0;
for(int i=2;i<=n;++i) scanf("%d",&pre[i]);
buildtree(1,n,1);
for(int i=n;i>=1;--i) ans[i]=query(1,pre[i]+1);
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
} (2.满二叉树,94ms,推荐---下标检索比指针快)
#include<stdio.h>
#include<math.h>
int pre[8005],ans[8005],tree[8005<<2];
void buildtree(int n,int left) {
for(int i=left;i<left+n;++i) tree[i]=1;
while(left!=1) {
for(int i=left/2;i<left;++i)
tree[i]=tree[i<<1]+tree[(i<<1)+1];
left=left/2;
}
}
int query(int u,int num,int left) {
--tree[u];
if(u>=left) return u;
if(tree[u<<1]<num) return query((u<<1)+1,num-tree[u<<1],left);
else return query(u<<1,num,left);
}
int main() {
int left,n;
scanf("%d",&n);
pre[1]=0;
left=1<<(int(log(n)/log(2))+1);
for(int i=2;i<=n;++i) scanf("%d",&pre[i]);
buildtree(n,left);
for(int i=n;i>=1;--i)
ans[i]=query(1,pre[i]+1,left)-left+1;
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
} 树状数组代码:
(79ms)
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int tree[10000],pre[10000],ans[10000];
int n;
#define lowbit(x) ((x)&-(x))
void add(int x,int d) {
while(x<=n) {
tree[x]+=d;
x+=lowbit(x);
}
}
int sum(int x) {
int sum=0;
while(x) {
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int findpos(int x) {
int l=1,r=n;
while(l<r) {
int mid=(l+r)>>1;
if(sum(mid)<x) l=mid+1;
else r=mid;
}
return l;
}
int main() {
scanf("%d",&n);
pre[1]=0;
for(int i=2;i<=n;++i) scanf("%d",&pre[i]);
for(int i=1;i<=n;++i) tree[i]=lowbit(i);
for(int i=n;i>0;--i) {
int x=findpos(pre[i]+1);
add(x,-1);
ans[i]=x;
}
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}poj 3468
线段树代码:
#include<stdio.h>
#define ll long long
using namespace std;
ll sum[100001<<2],add[100001<<2];
inline void push_up(int rt) {
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(int rt,int m) {
if(add[rt]) {
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=(m-(m>>1))*add[rt];
sum[rt<<1|1]+=(m>>1)*add[rt];
add[rt]=0;
}
}
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
void build(int l,int r,int rt) {
add[rt]=0;
if(l==r) {
scanf("%lld",&sum[rt]);
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
push_up(rt);
}
void update(int a,int b,ll c,int l,int r,int rt){
if(a<=l&&b>=r) {
sum[rt]+=(r-l+1)*c;
add[rt]+=c;
return;
}
push_down(rt,r-l+1);
int mid=(l+r)>>1;
if(a<=mid) update(a,b,c,lson);
if(b>mid) update(a,b,c,rson);
push_up(rt);
}
ll query(int a,int b,int l,int r,int rt) {
if(a<=l&&b>=r) return sum[rt];
push_down(rt,r-l+1);
int mid=(l+r)>>1;
ll ans=0;
if(a<=mid) ans+=query(a,b,lson);
if(b>mid) ans+=query(a,b,rson);
return ans;
}
int main() {
int n,m;
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--) {
char ch;
int a,b; ll c;
scanf(" %c",&ch);
if(ch=='C') {
scanf("%d%d%lld",&a,&b,&c);
update(a,b,c,1,n,1);
}
else {
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1,n,1));
}
}
}
京公网安备 11010502036488号