ACM资料大集合

源代码在线查看: pku 2182 线段树 从逆序数到数列.txt

软件大小: 803 K
上传用户: jessica12332145
关键词: ACM
下载地址: 免注册下载 普通下载 VIP

相关代码

				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				using namespace std;
				
				//PKU 2182 线段树 从逆序数到数列 
				#define PI 3.1415926
				#define MH make_heap
				#define OH pop_heap
				#define PH push_heap
				#define PB push_back
				#define OB pop_back
				#define NMAX 8050
				
				typedef struct ooptree
				{
				    int left;
				    int right;
				    int value;//value为-1,是非叶子结点,>=1,为叶子结点的值
				    int sum;//子树(包括自己)含有的未出现的数
				}ooptree;
				
				ooptree tree[NMAX*3];
				int a[NMAX];
				int ans[NMAX];
				
				void build(int p,int l,int r)
				{
				    tree[p].left=l;
				    tree[p].right=r;
				    if(r-l>=1) tree[p].value=-1;
				    else tree[p].value=r;
				    tree[p].sum=r-l+1;
				    if(r-l>=1)
				    {
				        build(2*p,l,(l+r)/2);
				        build(2*p+1,(l+r)/2+1,r);
				    }
				}
				
				int find(int k)
				{//查找已有元素中第K大的数
				    int p=1;
				    while(tree[p].value==-1)
				    {
				        if(k				        else {k-=tree[2*p].sum; p=2*p+1;}
				    }
				    return p;//注意返回的是结点号
				}
				
				void del(int p)
				{
				    while(p>=1) { tree[p].sum--; p=p/2;}
				}
				
				void print_tree()
				{
				     int i;
				     for(i=1;i				     {
				        printf("(%d,%d)",tree[i].value,tree[i].sum);
				        if(i==1 || i==3 || i==7) printf("\n");                  
				     }
				}
				void solve(int num)
				{
				    int i,p;
				    build(1,1,num);
				    for(i=num-1;i>=1;i--)
				    {
				     p=find(a[i]+1);
				     ans[i+1]=tree[p].value;
				     del(p);
				    }
				    p=find(1);
				    ans[1]=tree[p].value;
				    del(p);
				    for(i=1;i				}
				
				int main()
				{
				    int i,num;
				    scanf("%d",&num);
				    for(i=1;i				    solve(num);
				    return 0;
				}
				
							

相关资源