zoukankan      html  css  js  c++  java
  • HDU3577Fast Arrangement(线段树+lazy)

    Problem Description
    Chinese always have the railway tickets problem because of its' huge amount of passangers and stations. Now goverment need you to develop a new tickets query system.
    One train can just take k passangers. And each passanger can just buy one ticket from station a to station b. Each train cannot take more passangers any time. The one who buy the ticket earlier which can be sold will always get the ticket.
     
    Input
    The input contains servel test cases. The first line is the case number. In each test case:
    The first line contains just one number k( 1 ≤ k ≤ 1000 ) and Q( 1 ≤ Q ≤ 100000 )
    The following lines, each line contains two integers a and b, ( 1 ≤ a < b ≤ 1000000 ), indicate a query.
    Huge Input, scanf recommanded.
     
    Output
    For each test case, output three lines:
    Output the case number in the first line.
    If the ith query can be satisfied, output i. i starting from 1. output an blank-space after each number.
    Output a blank line after each test case.
     
    Sample Input
    1
    3 6
    1 6
    1 6
    3 4
    1 5
    1 2
    2 4
     
    Sample Output
    Case 1: 1 2 3 5
     

    即判断哪些人能上车;

    构建线段树的两种情况:

         1,知道范围,且范围不算太大,可以直接构建一个[1,Maxn]的线段树,这样左儿子和右儿子的编号(Lson=now<<1,Rson=now<<1|1)是固定的,不用标记。

         2,不提前构造,累加cnt为新节点标号,加一个root;每个点再ch[2]记录左右儿子的编号。

     lazy的使用,没啥可说的,注意该update就update。

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=1000005;
    int ans[maxn];
    struct Node
    {
        int l,r,v,lazy;
    }; 
    struct Tree
    {
         Node node[maxn<<2];
         void build(int l,int r,int numb)   
        {
             node[numb].l=l;
             node[numb].r=r;
             node[numb].v=0;
             node[numb].lazy=0;
             if(l==r) return;
             int mid=(l+r)>>1;
             build(l,mid,numb<<1);
             build(mid+1,r,numb<<1|1);
        }
        void PushUp(int numb)               
        {
             node[numb].v=max(node[numb<<1].v,node[numb<<1|1].v);
        }
        void PushDown(int numb)   
        {
             node[numb<<1].lazy+=node[numb].lazy;
             node[numb<<1|1].lazy+=node[numb].lazy;
             node[numb<<1].v+=node[numb].lazy;
             node[numb<<1|1].v+=node[numb].lazy;
             node[numb].lazy=0;             
        }
        void Insert(int l,int r,int numb)   
        {
            if(node[numb].l>=l&&node[numb].r<=r) 
            {
                node[numb].v+=1;
                node[numb].lazy+=1;
                return;
            }
            if(node[numb].lazy) PushDown(numb);
            int mid=(node[numb].r+node[numb].l)>>1;
            if(l>mid) Insert(l,r,numb<<1|1);
            else if(r<=mid) Insert(l,r,numb<<1);
            else{
                Insert(l,mid,numb<<1);
                Insert(mid+1,r,numb<<1|1);
            }
            PushUp(numb);    
       }
        int query(int l,int r,int numb)   
        {
            if(node[numb].l>=l&&node[numb].r<=r){
              return node[numb].v;
            }
            if(node[numb].lazy) PushDown(numb); 
            int mid=(node[numb].r+node[numb].l)>>1;
            if(l>mid) return query(l,r,numb<<1|1);
            else if(r<=mid) return query(l,r,numb<<1);
            else{
               return max(query(l,mid,numb<<1),query(mid+1,r,numb<<1|1)); 
            }
        }
    };
    Tree tree;
    int main()
    {
        int t,Case=1,len=0,k,m,a,b;
        scanf("%d",&t);
        while(t--){
            len=0;
            memset(ans,0,sizeof(ans));
            scanf("%d%d",&k,&m);
            tree.build(1,1000000,1);
            for(int i=0;i<m;i++){
                scanf("%d%d",&a,&b);
                b--;                   
                if(tree.query(a,b,1)<k){
                    ans[len++]=i+1;
                    tree.Insert(a,b,1);
                }
            }
            printf("Case %d:
    ",Case++);
            for(int i=0; i<len; i++)    
                printf("%d ",ans[i]);
            printf("
    
    ");
        }
        return 0;
    }
  • 相关阅读:
    动态添加LInk的分析
    ASP.NET内置对象-网页转向的4中方法
    网页生命周期-动态添加控件
    网页生命周期-控件事件执行顺序
    网页生命周期-PageLoad事件
    HyperLink 控件
    ListBox控件
    OptionMenu选项菜单
    Menubutton按钮弹出菜单
    Menu-右键弹出菜单
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7908490.html
Copyright © 2011-2022 走看看