zoukankan      html  css  js  c++  java
  • hdu 2711&&poj2182 Lost Cows (线段树)

    从后往前查第一个为0的奶牛肯定应该排在第一个。每次从后往前找到第一个为0的数,这个数应该插在第j位。查找之后,修改节点的值为极大值,当整棵树的最小值不为0的时候查找结束。

    至于这种查找修改的操作,再没有比线段树效率更高的了。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define N 8005
    #define M 16100
    struct node
    {
        int x,y;
        int min;
        int flag;
    }a[N*3];
    int b[N],c[N];
    int Min(int x,int y)
    {
        if(x<y)
            return x;
        else
            return y;
    }
    void ChangeTree(int t,int k)
    {
        a[t].flag+=k;
        a[t].min+=k;
        return ;
    }
    void CreatTree(int t,int x,int y)
    {
        a[t].x=x;
        a[t].y=y;
        a[t].flag=0;
        if(x==y)
        {
            a[t].min=b[x];
            return ;
        }
        int temp=t*2;
        int mid=(a[t].x+a[t].y)/2;
        CreatTree(temp,x,mid);
        CreatTree(temp+1,mid+1,y);
        a[t].min=Min(a[temp].min,a[temp+1].min);
        return ;
    }
    void InsertTree(int t,int x,int y,int k)
    {
        if(a[t].x==x&&a[t].y==y)
        {
            ChangeTree(t,k);
            return ;
        }
        int temp=t*2;
        int mid=(a[t].x+a[t].y)/2;
        if(a[t].flag)
        {
            ChangeTree(temp,a[t].flag);
            ChangeTree(temp+1,a[t].flag);
            a[t].flag=0;
        }
        if(y<=mid)
            InsertTree(temp,x,y,k);
        else if(x>mid)
            InsertTree(temp+1,x,y,k);
        else
        {
            InsertTree(temp,x,mid,k);
            InsertTree(temp+1,mid+1,y,k);
        }
        a[t].min=Min(a[temp].min,a[temp+1].min);
        return ;
    }
    int FindTree(int t)
    {
        if(a[t].x==a[t].y)
        {
            if(a[t].min==0)
                return a[t].x;
            else
                return 0;
        }
        int temp=t*2;
        if(a[t].flag)
        {
            ChangeTree(temp,a[t].flag);
            ChangeTree(temp+1,a[t].flag);
            a[t].flag=0;
        }
        if(a[temp+1].min==0)
            return FindTree(temp+1);
        else
            return FindTree(temp);
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            int i,j;
            b[1]=0;
            for(i=2;i<=n;i++)
                scanf("%d",&b[i]);
            CreatTree(1,1,n);
            j=1;
            while(a[1].min==0)
            {
                int tt;
                tt=FindTree(1);
                if(!tt)
                    tt=1;
                c[tt]=j++;
                InsertTree(1,tt,tt,M);
                InsertTree(1,tt,n,-1);
            }
            for(i=1;i<=n;i++)
                printf("%d
    ",c[i]);
        }
        return 0;
    }


  • 相关阅读:
    命名规则
    数据库的基本概念(三大范式,数据)
    集合的排序
    装箱拆箱
    异常处理
    单行函数
    表管理
    创建表,插入列....
    PL/SQL 块
    单行函数的案例
  • 原文地址:https://www.cnblogs.com/riskyer/p/3228836.html
Copyright © 2011-2022 走看看