zoukankan      html  css  js  c++  java
  • 第17届科大讯飞杯 H-时空栈 (线段树 + 思维)

    题目:传送门

    题意

     思路

    先对时间 t 离散化,开线段树维护,对于入栈操作,我们对区间 [ t[i] , n ]  加 1,出栈操作则是减 1,线段树维护一个区间最小值。

    对于查询操作,我们通过线段树可以很快的知道,当前时间点 t[i] 对应的栈的元素个数 x,然后, 我们要查询在 t[ i ] 时间前最后一个小于 x 的时间点 T,此时对应的栈的元素个数必定等于 x - 1,且 T + 1 时间点对应的操作必定是入栈操作,此时栈的元素个数为 x,此时的栈即为我们查询的时间点 t[ i ] 对应的栈,那么答案就是此时入栈的数。

     

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int N = 1e6 + 5;
    
    struct note {
        int mi, lz;
    }t[N];
    
    int Time[N], tmp[N], val[N], op[N];
    
    int real_val[N];
    
    void push_down(int rt) { 
    
        if(t[rt].lz) {
    
            t[rt << 1].mi += t[rt].lz;
    
            t[rt << 1 | 1].mi += t[rt].lz;
    
            t[rt << 1].lz += t[rt].lz;
    
            t[rt << 1 | 1].lz += t[rt].lz;
    
            t[rt].lz = 0;
    
        }
    
    }
    
    void update(int rt, int l, int r, int L, int R, int V) {  /// 区间更新
    
        if(L <= l && r <= R) {
    
            t[rt].mi += V; t[rt].lz += V;
    
            return ;
    
        }
    
        push_down(rt);
    
        int mid = (l + r) >> 1;
    
        if(L <= mid) update(rt << 1, l, mid, L, R, V);
    
        if(R > mid) update(rt << 1 | 1, mid + 1, r, L, R, V);
    
        t[rt].mi = min(t[rt << 1].mi, t[rt << 1 | 1].mi);
    
    }
    
    int query1(int rt, int l, int r, int pos) { /// 单点查询
    
        if(l == r && l == pos) return t[rt].mi;
    
        push_down(rt);
    
        int mid = (l + r) >> 1;
    
        if(pos <= mid) return query1(rt << 1, l, mid, pos);
    
        else return query1(rt << 1 | 1, mid + 1, r, pos);
    
    }
    
    int query2(int rt, int l, int r, int pos, int limit) { /// 找区间[l,r]内在点 pos 前最后一个小于 limit 的坐标
    
        if(l == r) {
    
            if(t[rt].mi < limit) return l;
    
            return 0;
    
        }
    
        push_down(rt);
    
        int mid = (l + r) >> 1;
    
        int ans = 0;
    
        if(pos > mid && t[rt << 1 | 1].mi < limit) ans = query2(rt << 1 | 1, mid + 1, r, pos, limit); /// 先找右半区间
    
        if(ans) return ans; /// 找到了就直接返回
    
        return query2(rt << 1, l, mid, pos, limit); /// 找不到再去左半区间找
    
    }
    
    int main() {
    
        int n;
    
        scanf("%d", &n);
    
        rep(i, 1, n) {
    
            scanf("%d %d", &op[i], &Time[i]);
    
            if(op[i] == 0) scanf("%d", &val[i]);
    
            tmp[i] = Time[i];
    
        }
    
        sort(tmp + 1, tmp + 1 + n);
    
        rep(i, 1, n) {
    
            Time[i] = lower_bound(tmp + 1, tmp + 1 + n, Time[i]) - tmp; /// 离散化
    
            real_val[Time[i]] = val[i]; 
    
        }
    
        rep(i, 1, n) {
    
            if(op[i] == 0) update(1, 1, n, Time[i], n, 1); /// 区间更新 Time[i] ~ n 区间加 1
    
            else if(op[i] == 1) update(1, 1, n, Time[i], n, -1); /// 区间更新 Time[i] ~ n 区间减 1
    
            else {
    
                int limit = query1(1, 1, n, Time[i]); /// 先查询时间点 Time[i] 对应的栈的元素个数
                
                int Time_Point = query2(1, 1, n, Time[i], limit); /// 查询区间 1 ~ Time[i] 最后一个栈的元素个数小于 limit 的时间点
                
                int ans = real_val[Time_Point + 1];  /// Time_Point + 1 入栈的元素就是答案
    
                printf("%d
    ", ans);
    
            }
    
        }
    
        return 0;
    
    }
     
  • 相关阅读:
    SQL GUID和自增列做主键的优缺点
    python __future__ 的几种特性
    数据库中文乱码处理
    Android_Intent意图详解
    Windows Server 2012 R2超级虚拟化之六 Hyper-v Replica 2.0和Live migrations
    如今网站定位,需立足于用户
    Hibernate 数据的批量插入、更新和删除
    paip.提升用户体验---论文本编辑器的色彩方案
    时间管理方法学习
    网站优化:从搜索引擎到社交网络的艰难转变
  • 原文地址:https://www.cnblogs.com/Willems/p/12872663.html
Copyright © 2011-2022 走看看