7 a/7 b/6 c/5 d/4 e/3 f/2 g/1 7 a/1 b/2 c/3 d/4 e/5 f/6 g/7 7 a/3 b/6 c/4 d/7 e/2 f/5 g/1 0
Sample Output
(a/7(b/6(c/5(d/4(e/3(f/2(g/1))))))) (((((((a/1)b/2)c/3)d/4)e/5)f/6)g/7)
(((a/3)b/6(c/4))d/7((e/2)f/5(g/1)))
题意:给出一些结点,每个结点有两个值,lable和priority(都是唯一的),要求构成一个笛卡尔树,按lable时二叉排序树,按priority是大根堆(不一定是二叉树)。
分析:先把结点按lable排序,从小到大依次插入,这样每次插入的结点就是要插到排序二叉树的最右边,首先要沿着右儿子找到最右边的结点(再无右儿子),然后分两种情况,最右结点的priority和当前插入结点的priority比较,若大于则直接将当前插入结点接到右子树,否则让当前插入节点取代最右结点位置并将原来最右结点及其子树接到当前插入结点的左子树。
//笛卡尔树
#include
#include
#include
#include
using namespace std;
const int maxn=55555;
struct node{
int value,l,r,fa;
char str[20];
friend bool operator < (const node&a,const node&b){
return strcmp(a.str,b.str)<0;
}
};
node nodes[maxn];
int n;
void insert(int i)
{
int j=i-1;
while(nodes[j].value
还可以使用线段树来做,同样先把字母排序,然后建造出一个维护最大值的线段树以及位置,并进行递归输出
//线段树,res数组记录最大数据,pos数组记录坐标
#include
#include
#include
#include
using namespace std;
const int maxn=55555;
struct node{
int data;
char str[50];
friend bool operator <(const node&a,const node&b){
return strcmp(a.str,b.str)<0;
}
};
node save[maxn];
int res[maxn<<2],pos[maxn<<2],n;
void pushup(int num)
{
res[num]=max(res[num<<1],res[num<<1|1]);
if(res[num<<1]>res[num<<1|1]){
pos[num]=pos[num<<1];
}else{
pos[num]=pos[num<<1|1];
}
}
void build(int num,int left,int right)
{
if(left==right){
res[num]=save[left].data;
pos[num]=left;
return ;
}
int mid=(left+right)>>1;
build(num<<1,left,mid);
build(num<<1|1,mid+1,right);
pushup(num);
}
int query(int num,int left,int right,int l,int r)
{
if(l<=left&&right<=r){
return pos[num];
}
int mid=(left+right)>>1;
if(r<=mid){
return query(num<<1,left,mid,l,r);
}else if(l>mid){
return query(num<<1|1,mid+1,right,l,r);
}else{
int lmost=query(num<<1,left,mid,l,mid);
int rmost=query(num<<1|1,mid+1,right,mid+1,r);
if(save[lmost].data<=save[rmost].data){
return rmost;
}else{
return lmost;
}
}
}
void print(int l,int r)
{
if(l>r){
return ;
}
if(l==r){
printf("(%s/%d)",save[l].str,save[l].data);
return ;
}
int mid=query(1,1,n,l,r);
printf("(");
print(l,mid-1);
printf("%s/%d",save[mid].str,save[mid].data);
print(mid+1,r);
printf(")");
}
int main()
{
while(scanf("%d",&n)!=EOF&&n){
for(int i=1;i<=n;i++){
scanf(" %[a-z]/%d",save[i].str,&save[i].data);
}
sort(save+1,save+1+n);
build(1,1,n);
// for(int i=1;i<=13;i++){
// printf("%d ",res[i]);
// }
// cout<