前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >51Nod-1249-近似有序区间

51Nod-1249-近似有序区间

作者头像
f_zyj
发布2018-01-09 10:55:53
5050
发布2018-01-09 10:55:53
举报
文章被收录于专栏:ACM小冰成长之路

ACM模版

描述

描述
描述

题解

image.png
image.png

代码

代码语言:javascript
复制
#include <cstdio>
#include <iostream>

#define ls rt << 1
#define rs rt << 1 | 1

using namespace std;

const int MAXN = 5e4 + 10;

int n;
int S[MAXN];
int vis[MAXN];
int sum[MAXN];
int tree[MAXN << 2];

void build(int rt, int l, int r)
{
    if (l == r)
    {
        tree[rt] = S[l];
        return ;
    }

    int m = (l + r) >> 1;
    build(ls, l, m);
    build(rs, m + 1, r);

    tree[rt] = max(tree[ls], tree[rs]);
}

int query(int rt, int l, int r, int x, int y, int mx)
{
    if (l == r)
    {
        if (S[l] >= mx)
        {
            return l;
        }

        return 0;
    }

    int m = (l + r) >> 1, k = 0;
    if (tree[rt] >= mx)
    {
        if (x <= m)
        {
            k = query(ls, l, m, x, y, mx);
        }
        if (k == 0 && y > m)
        {
            k = query(rs, m + 1, r, x, y, mx);
        }
    }

    return k;
}

int main()
{
    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        cin >> S[i];
    }

    build(1, 1, n);

    for (int i = n; i >= 1; i--)
    {
        if (S[i] > S[i + 1])
        {
            sum[i] = 1;
            vis[i] = i;
        }
        else
        {
            vis[i] = vis[i + 1];
            sum[i] = sum[i + 1] + 1;
            int mx = S[vis[i]];
            int l = vis[i] + 1, r = l;

            while (S[r] >= S[i])
            {
                r = vis[r] + 1;
            }
            r -= 1;

            while (l <= r)
            {
                mx = query(1, 1, n, l, r, mx);
                if (mx != 0)
                {
                    sum[i]++;
                }
                else
                {
                    break;
                }

                l = mx + 1;
                vis[i] = mx;
                mx = S[mx];
            }
        }
    }

    long long ans = 0;
    for (int i = 1; i <= n; i++)
    {
        ans += sum[i];
    }
    cout << ans << '\n';

    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年09月25日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 描述
  • 题解
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档