• poj 2352 Stars 夜


    http://poj.org/problem?id=2352

    题目大意:

    给出N个点 点的顺序是按y非递减给出的

    level是这个点左下方点的个数

    求各个level的数量

    思路:

    由于给的点有顺序 所以就简单了

    一般用树状数组或线段树就可以

    我用了平衡树 是为了练习啦 写的相当烂

    用平衡树 不断地插入更新就可以了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    
    using namespace std;
    
    const int N=15100;
    struct node
    {
        int x;//x坐标
        int l,r,f;//左右孩子 和父节点
        int sum;
        int h;
    }mem[N];
    int treehead;//树的头结点
    int ans[N];//答案
    void Leftturn(int i)//左旋转
    {
        int f=mem[i].f;
        int r=mem[i].r;
        if(f==-1)
        {
            mem[r].f=-1;treehead=r;
        }
        else
        {
            mem[r].f=f;
            if(mem[f].l==i)
            mem[f].l=r;
            else
            mem[f].r=r;
        }
        mem[i].r=mem[r].l;
        mem[mem[r].l].f=i;
        mem[r].l=i;
        mem[i].f=r;
        mem[i].h=max(mem[mem[i].l].h,mem[mem[i].r].h)+1;
        mem[i].sum=mem[mem[i].l].sum+mem[mem[i].r].sum+1;
        mem[r].h=max(mem[mem[r].l].h,mem[mem[r].r].h)+1;
        mem[r].sum=mem[mem[r].l].sum+mem[mem[r].r].sum+1;
    }
    void Rightturn(int i)//右旋转
    {
        int f=mem[i].f;
        int l=mem[i].l;
        if(f==-1)
        {
            mem[l].f=-1;treehead=l;
        }
        else
        {
            mem[l].f=f;
            if(mem[f].l==i)
            mem[f].l=l;
            else
            mem[f].r=l;
        }
        mem[i].l=mem[l].r;
        mem[mem[l].r].f=i;
        mem[l].r=i;
        mem[i].f=l;
        mem[i].h=max(mem[mem[i].l].h,mem[mem[i].r].h)+1;
        mem[i].sum=mem[mem[i].l].sum+mem[mem[i].r].sum+1;
        mem[l].h=max(mem[mem[l].l].h,mem[mem[l].r].h)+1;
        mem[l].sum=mem[mem[l].l].sum+mem[mem[l].r].sum+1;
    }
    
    void update(int i)//对不平衡点的更新
    {
        if(mem[mem[i].l].h<mem[mem[i].r].h)
        {
            int x=mem[i].r;
            if(mem[mem[x].l].h<mem[mem[x].r].h)
            {
                Leftturn(i);
            }
            else
            {
                Rightturn(mem[i].r);
                Leftturn(i);
            }
        }
        else
        {
            int x=mem[i].l;
            if(mem[mem[x].l].h>mem[mem[x].r].h)
            {
                Rightturn(i);
            }
            else
            {
                Leftturn(mem[i].l);
                Rightturn(i);
            }
        }
    }
    void insert(int i,int k,int s)//插入新的点
    {
        if(mem[i].x<=mem[k].x)
        {
            if(mem[i].r!=0)
            {
                insert(mem[i].r,k,s+mem[mem[i].l].sum+1);//继续向右插入 注意记录有多少比他小的点
            }
            else
            {
                ++ans[s+mem[mem[i].l].sum+1];
                mem[i].r=k;
                mem[k].f=i;
            }
        }
        else
        {
            if(mem[i].l!=0)
            {
                insert(mem[i].l,k,s);
            }
            else
            {
                ++ans[s];
                mem[i].l=k;
                mem[k].f=i;
            }
        }
        mem[i].h=max(mem[mem[i].l].h,mem[mem[i].r].h)+1;//对路径上的点要更新
        mem[i].sum=mem[mem[i].l].sum+mem[mem[i].r].sum+1;
        if(abs(mem[mem[i].l].h-mem[mem[i].r].h)>1)
        {
            update(i);
        }
    }
    int main()
    {
        int n;
        scanf("%d",&n);
            memset(ans,0,sizeof(ans));
            mem[0].l=mem[0].r=-1;//把0这个点设成假的所以叶子节点
            mem[0].sum=0;
            mem[0].h=-1;
            int y;
            scanf("%d %d",&mem[1].x,&y);
            mem[1].h=0;
            mem[1].l=mem[1].r=0;
            mem[1].sum=1;mem[1].f=-1;
            treehead=1;//头结点
            ++ans[0];
            for(int i=2;i<=n;++i)
            {
                scanf("%d %d",&mem[i].x,&y);
                mem[i].l=mem[i].r=0;
                mem[i].sum=1;mem[i].h=0;
                insert(treehead,i,0);
            }
            for(int i=0;i<n;++i)
            {
                printf("%d\n",ans[i]);
            }
        return 0;
    }
  • 相关阅读:
    C#和sqlserver中生成新的32位GUID
    IIS7下swfupload上传大文件出现404错误
    jQuery 判断是否为数字的方法 及 转换数字函数
    js数组与字符串的相互转换方法
    jquery 中如何将数组转化为json字符串,然后再转化回来?
    Firemonkey Android 虚拟机
    Eclipse apk 签名
    win10 修改hosts
    eclipse 预览Android界面报错
    夜神模拟器
  • 原文地址:https://www.cnblogs.com/liulangye/p/2591691.html
Copyright © 2020-2023  润新知