码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 193 D. Two Segments(线段树)

时间:2015-04-07 21:49:36      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

机智的线段树题,

参考了这个题解http://www.cnblogs.com/keam37/p/4335914.html

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;

#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)

const int N = 300005;

int n, v[N], p[N];

struct Node {
    int l, r, Min, lazy, val1, val2;
    void gao(int x) {
        lazy += x;
        Min += x;
    }
} node[N * 4];

void build(int l, int r, int x = 0) {
    node[x].l = l; node[x].r = r;
    node[x].Min = node[x].lazy = node[x].val2 = 0;
    node[x].val1 = r - l + 1;
    if (l == r) return;
    int mid = (l + r) / 2;
    build(l, mid, lson(x));
    build(mid + 1, r, rson(x));
}

void pushdown(int x) {
    if (node[x].lazy) {
       node[lson(x)].gao(node[x].lazy);
       node[rson(x)].gao(node[x].lazy);
    }
    node[x].lazy = 0;
}

void pushup(int x) {
    node[x].Min = min(node[lson(x)].Min, node[rson(x)].Min);
    node[x].val1 = (node[lson(x)].Min == node[x].Min) * node[lson(x)].val1 + (node[rson(x)].Min == node[x].Min) * node[rson(x)].val1;
    node[x].val2 = (node[lson(x)].Min == node[x].Min + 1) * node[lson(x)].val1 + (node[rson(x)].Min == node[x].Min + 1) * node[rson(x)].val1;
    node[x].val2 += (node[lson(x)].Min == node[x].Min) * node[lson(x)].val2 + (node[rson(x)].Min == node[x].Min) * node[rson(x)].val2;
}

void add(int l, int r, int val, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) {
        node[x].gao(val);
        return;
    }
    pushdown(x);
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) add(l, r, val, lson(x));
    if (r > mid) add(l, r, val, rson(x));
    pushup(x);
}

ll ans;

void query(int l, int r, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) {
         if (node[x].Min == 1) {
            ans += node[x].val1 + node[x].val2;
         } else if (node[x].Min == 2)
            ans += node[x].val1;
         return;
    }
    pushdown(x);
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) query(l, r, lson(x));
    if (r > mid) query(l, r, rson(x));
    pushup(x);
}

int main() {
    scanf("%d", &n);
    int tmp;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &tmp);
        v[tmp] = i;
    }
    ans = 0;
    build(1, n);
    memset(p, 0, sizeof(p));
    for (int i = n; i >= 1; i--) {
        p[v[i]] = i;
        int x = p[v[i] - 1], y = p[v[i] + 1];
        if (x > y) swap(x, y);
        if (x) {
            add(i, x - 1, 1);
            add(y, n, -1);
        } else if (y) add(i, y - 1, 1);
        else add(i, n, 1);
        query(i, n);
    }
    printf("%I64d\n", ans - n);
    return 0;
}


Codeforces 193 D. Two Segments(线段树)

标签:

原文地址:http://blog.csdn.net/accelerator_/article/details/44924869

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!