Codeforces 780G Andryusha and Nervous Barriers 线段树套set || 线段树套单调栈
Posted cjlhy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 780G Andryusha and Nervous Barriers 线段树套set || 线段树套单调栈相关的知识,希望对你有一定的参考价值。
Andryusha and Nervous Barriers
问题本质我们只需要找出每个线段两端下面第一个碰到的是哪个线段就好啦。
按照 h 排序我们就能用线段树套set 不管维护什么都能维护出这个东西,但是 如果set里维护 u + s的话,就能优化成单调栈, 好优秀啊。
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) a += b; if(a >= mod) a -= mod; template<class T, class S> inline void sub(T& a, S b) a -= b; if(a < 0) a += mod; template<class T, class S> inline bool chkmax(T& a, S b) return a < b ? a = b, true : false; template<class T, class S> inline bool chkmin(T& a, S b) return a > b ? a = b, true : false; int h, w, n; int toL[N], toR[N]; int to[N]; int hs[N]; set<int> start; set<PII> seg; int dp[N]; struct Node int u, l, r, s; bool operator < (const Node& rhs) const return u < rhs.u; void read() scanf("%d%d%d%d", &u, &l, &r, &s); a[N]; vector<PII> vc; struct segmentTree #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 set<PII> a[N << 2]; void Insert(int p, PII v, int l, int r, int rt) a[rt].insert(v); if(l == r) return; int mid = l + r >> 1; if(p <= mid) Insert(p, v, lson); else Insert(p, v, rson); void Delete(int p, PII v, int l, int r, int rt) a[rt].erase(v); if(l == r) return; int mid = l + r >> 1; if(p <= mid) Delete(p, v, lson); else Delete(p, v, rson); void query(int L, int R, int x, int y, int l, int r, int rt) if(R < l || r < L || R < L) return; if(L <= l && r <= R) auto it = a[rt].lower_bound(mk(x, -inf)); while(it != a[rt].end() && it->fi <= y) vc.push_back(*it); ++it; return; int mid = l + r >> 1; query(L, R, x, y, lson); query(L, R, x, y, rson); Tree; int main() scanf("%d%d%d", &h, &w, &n); for(int i = 1; i <= w; i++) start.insert(i); for(int i = 1; i <= n; i++) a[i].read(); sort(a + 1, a + 1 + n); for(int i = 1; i <= n; i++) hs[i] = a[i].u; for(int i = n; i >= 1; i--) if(a[i].u + a[i].s < h + 1) continue; while(1) auto it = start.lower_bound(a[i].l); if(it == start.end() || *it > a[i].r) break; to[*it] = i; start.erase(it); for(int i = n; i >= 1; i--) int p = upper_bound(hs + 1, hs + 1 + n, a[i].u + a[i].s) - hs - 1; Tree.query(i + 1, p, a[i].l, a[i].r, 1, n, 1); for(auto &t : vc) if(t.se < 0) toL[-t.se] = i; else toR[t.se] = i; Tree.Delete(abs(t.se), t, 1, n, 1); if(a[i].l - 1 > 0) Tree.Insert(i, mk(a[i].l - 1, -i), 1, n, 1); if(a[i].r + 1 <= w) Tree.Insert(i, mk(a[i].r + 1, i), 1, n, 1); vc.clear(); for(int i = 1; i <= n; i++) if(a[i].l == 1) toL[i] = toR[i]; if(a[i].r == w) toR[i] = toL[i]; dp[0] = 1; for(int i = 1; i <= n; i++) dp[i] = (dp[toL[i]] + dp[toR[i]]) % mod; int ans = 0; for(int i = 1; i <= w; i++) add(ans, dp[to[i]]); printf("%d\n", ans); return 0; /* */
以上是关于Codeforces 780G Andryusha and Nervous Barriers 线段树套set || 线段树套单调栈的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 781E Andryusha and Nervous Barriers 线段树 单调栈
CF781A Andryusha and Colored Balloons
骁龙778G和骁龙780G差别大不大 骁龙778G和骁龙780G选哪个好