Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017 - Final Round Div. 2 Edition) E - Nikita and stack 線段樹好題
阿新 • • 發佈:2018-06-25
long long 但是 make div 計算 space its void lse
http://codeforces.com/contest/760/problem/E
題目大意:現在對棧有m個操作,但是順序是亂的,現在每輸入一個操作要求你輸出當前的棧頂,
註意,已有操作要按它們的時間順序進行。
思路:線段樹好題啊啊,我們把push當成+1, pop當成-1,按操作的位置建立線段樹,那麽如何
尋找棧頂呢,我們計算每個點的後綴,棧頂就是下標最大的>0的後綴,我們拿後綴建立線段樹,
剩下的就是區間加減法,和求區間最大值啦。
#include<bits/stdc++.h> #define LL long long #define fi first #definese second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1e5 + 7; const int M = 1e6 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int n, lazy[N << 2], mx[N << 2], a[N]; void pushDown(intrt) { if(!lazy[rt]) return; lazy[rt << 1] += lazy[rt]; lazy[rt << 1 | 1] += lazy[rt]; mx[rt << 1] += lazy[rt]; mx[rt << 1 | 1] += lazy[rt]; lazy[rt] = 0; } void update(int L, int R, int v, int l, int r, int rt) { if(l >= L && r <= R) { mx[rt]+= v; lazy[rt] += v; return; } int mid = l + r >> 1; pushDown(rt); if(L <= mid) update(L, R, v, l, mid, rt << 1); if(R > mid) update(L, R, v, mid + 1, r, rt << 1 | 1); mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]); } int query(int l, int r, int rt) { if(mx[rt] <= 0) return -1; if(l == r) return l; int mid = l + r >> 1; pushDown(rt); if(mx[rt << 1 | 1] > 0) return query(mid + 1, r, rt << 1 | 1); else return query(l, mid, rt << 1); } int main(){ scanf("%d", &n); int T = n; while(T--) { int op, id, x; scanf("%d%d", &id, &op); if(op == 1) { scanf("%d", &x); a[id] = x; update(1, id, 1, 1, n, 1); } else { update(1, id, -1, 1, n, 1); } int idx = query(1, n, 1); if(idx == -1) puts("-1"); else printf("%d\n", a[idx]); } return 0; } /* */
Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017 - Final Round Div. 2 Edition) E - Nikita and stack 線段樹好題