Codeforces 193D Two Segments (线段树)
2016-05-24 00:35
369 查看
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <map> #include <set> #include <algorithm> #include <ctime> #include <cstdlib> #include <functional> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; #define eps 1e-10 #define N 300030 #define B 20 #define M 3000020 #define inf 0x3f3f3f3f #define LL long long #define pii pair<int, int> #define MP make_pair #define fi first #define se second #define mod 1000000007 #define ls (i << 1) #define rs (ls | 1) #define md (ll + rr >> 1) #define lson ll, md, ls #define rson md + 1, rr, rs int mi1[N << 2], mi2[N << 2], s1[N << 2], s2[N << 2], lazy[N << 2]; int n, a , f ; void build(int ll, int rr, int i) { mi1[i] = 0, s1[i] = rr - ll + 1; mi2[i] = inf, s2[i] = 0; if(ll == rr) return; build(lson); build(rson); } LL ans; int t; void upd(int v, int i) { mi1[i] += v; mi2[i] += v; lazy[i] += v; } void push_down(int i) { if(lazy[i]) { upd(lazy[i], ls); upd(lazy[i], rs); lazy[i] = 0; } } void calc(int i, int x, int v) { if(v == 0) return; if(x < mi1[i]) { mi2[i] = mi1[i], s2[i] = s1[i]; mi1[i] = x, s1[i] = v; } else if(x == mi1[i]) { s1[i] += v; } else if(x < mi2[i]) { mi2[i] = x, s2[i] = v; } else if(x == mi2[i]) { s2[i] += v; } } void push_up(int i) { mi1[i] = mi1[ls], s1[i] = s1[ls]; mi2[i] = mi2[ls], s2[i] = s2[ls]; calc(i, mi1[rs], s1[rs]); calc(i, mi2[rs], s2[rs]); } void update(int l, int r, int v, int ll, int rr, int i) { if(ll == l && rr == r) { upd(v, i); return; } push_down(i); if(r <= md) update(l, r, v, lson); else if(l > md) update(l, r, v, rson); else { update(l, md, v, lson); update(md + 1, r, v, rson); } push_up(i); } void query(int l, int r, int ll, int rr, int i) { if(ll == l && rr == r) { calc(t, mi1[i], s1[i]); calc(t, mi2[i], s2[i]); return; } push_down(i); if(r <= md) query(l, r, lson); else if(l > md) query(l, r, rson); else { query(l, md, lson); query(md + 1, r, rson); } } int main() { scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); f[a[i]] = i; } build(1, n, 1); ans = 0; t = (N << 2) - 1; for(int i = 1; i <= n; ++i) { int l = -1, r = -1; if(f[i] > 1 && a[f[i] - 1] <= i) l = a[f[i] - 1]; if(f[i] < n && a[f[i] + 1] <= i) r = a[f[i] + 1]; if(l > r) swap(l, r); if(r == -1) update(1, i, 1, 1, n, 1); else if(l == -1) { update(r + 1, i, 1, 1, n, 1); } else { update(r + 1, i, 1, 1, n, 1); update(1, l, -1, 1, n, 1); } mi1[t] = inf, mi2[t] = inf; query(1, i, 1, n, 1); if(mi1[t] == 1) ans += s1[t]; if(mi2[t] == 2) ans += s2[t]; } printf("%lld\n", ans - n); return 0; }
相关文章推荐
- HDU5694-BD String-数学归纳找规律
- spark 运行问题记录
- 必须跟你说点事《TCP 三次握手》
- 微博推荐算法简述
- SQL Server error '80040e14'的处理
- Android Drawable - Inset Drawable使用详解(附图)
- 容易被忽略的事----sql语句中select语句的执行顺序
- 学习篇---幸运转盘
- Hadoop
- Spark Streaming源码解读之JobScheduler内幕实现和深度思考
- 记录下自己的脑X错误
- android之context(上下文)、五大布局
- 类的其他特性
- 一个文件系统过滤驱动的demo
- android开发笔记之Gson解析
- 特殊二极管的学习
- win8 win10 安装msi 提示2502、2503的错误代码
- shell执行三种方法
- Java-反射机制reflect
- ios 画图板