• HDU 4960 Handling the past 2014 多校9 线段树


    首先确定的基本思想是按时间离散化后来建线段树,对于每个操作插入到相应的时间点上

    但是难就难在那个pop操作,我之前对pop操作的处理是找到离他最近的那个点删掉,但是这样对于后面的peak操作,如果时间戳还在pop前面,那就需要还原之前的pop操作,这弄得很不方便

    于是就有了一种类似扫描线的做法,对于push操作+1,pop操作-1,对于每次peak操作,从他这点往左走,找到第一个>0的点即可

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL __int64
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    using namespace std;
    const int N = 50010;
    int sum[N<<2],rsum[N<<2];
    int d[N<<2];
    int q[N],A[N],tmp[N],t[N];
    int n;
    void build(int rt,int l,int r)
    {
        sum[rt]=rsum[rt]=0;
        if (l>=r){
           return;
        }
        int mid=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void up(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        rsum[rt]=max(rsum[rt<<1|1],sum[rt<<1|1]+rsum[rt<<1]);
    }
    void update(int val,int pos,int loc,int rt,int l,int r)
    {
        if (l>=r){
            sum[rt]=val;
            rsum[rt]=val;
            if (val>0) d[rt]=A[loc];
            //if (val<0) rsum[rt]=0;
            return;
        }
        int mid=(l+r)>>1;
        if (pos<=mid)
        update(val,pos,loc,lson);
        else
        update(val,pos,loc,rson);
        up(rt);
    }
    int s;
    int query(int pos,int rt,int l,int r)
    {
        if (r<=pos){
            if (s+rsum[rt]<=0){
                s+=sum[rt];
                return -1;
            }
        }
        if (l>=r){
            return d[rt];
        }
        int mid=(l+r)>>1;
        if (pos<=mid) return query(pos,lson);
        int res=-1;
        res=query(pos,rson);
        if (res!=-1) return res;
        return query(pos,lson);
    
    }
    int main()
    {
        char str[10];
        int kase=0;
        while (scanf("%d",&n)!=EOF)
        {
            if (n==0) break;
            for (int i=1;i<=n;i++){
                scanf("%s",str);
                if (str[1]=='u'){
                    q[i]=1;
                    scanf("%d%d",&A[i],&tmp[i]);
                }
                else
                if (str[1]=='o'){
                    q[i]=2;
                    scanf("%d",&tmp[i]);
                }
                else{
                    q[i]=3;
                    scanf("%d",&tmp[i]);
                }
                t[i]=tmp[i];
            }
            printf("Case #%d:
    ",++kase);
            sort(t+1,t+1+n);
            for (int i=1;i<=n;i++){
                int pos=lower_bound(t+1,t+1+n,tmp[i])-t;
                tmp[i]=pos;
                //cout<<tmp[i]<<endl;
            }
            build(1,1,n);
            for (int i=1;i<=n;i++){
                if (q[i]==1){
                    update(1,tmp[i],i,1,1,n);
                }
                else
                if (q[i]==2){
                    update(-1,tmp[i],i,1,1,n);
                }
                else{
                    if (tmp[i]<=1){
                     printf("-1
    ");
                     continue;
                    }
                    s=0;
                    int ans=query(tmp[i]-1,1,1,n);
                    printf("%d
    ",ans);
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    git
    浏览器喧嚷过程
    B/S架构与C/S架构
    simpleDateFormat
    oracle中case when的用法
    Java程序利用Jdbc连接数据库
    List 和 Set与Map
    队列和栈
    toString方法分析
    java中的构造器
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3963020.html
Copyright © 2020-2023  润新知