ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解P3165 [CQOI2014]排序机械臂

2021-02-02 12:05:20  阅读:185  来源: 互联网

标签:int 题解 P3165 tr mid siz pushdown CQOI2014 lz


P3165 [CQOI2014]排序机械臂
一道Splay模板题,只不过需要注意一些细节

直接上代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
typedef pair<int, int> PII;

struct tree
{
    int s[2], v, p, siz, lz;
    void init(int _v, int _p)
    {
        v = _v, p = _p, siz = 1;
    }
} tr[N];
int root, idx, hi[N];
PII poi[N];

bool cmp(PII a, PII b)
{
    if (a.first == b.first)
        return a.second < b.second;
    return a.first < b.first;
}//注意排序规则

void pushup(int p)
{
    tr[p].siz = tr[tr[p].s[0]].siz + tr[tr[p].s[1]].siz + 1;
}

void pushdown(int p)
{
    if (tr[p].lz)
    {
        tr[p].lz = 0;
        if (tr[p].s[0])
            tr[tr[p].s[0]].lz ^= 1;
        if (tr[p].s[1])
            tr[tr[p].s[1]].lz ^= 1;
        swap(tr[p].s[0], tr[p].s[1]);
    }
}

int build(int l, int r, int p)
{
    int mid = (l + r) >> 1;
    tr[mid].init(hi[mid], p), poi[mid] = {hi[mid], mid};
    if (l < mid)
        tr[mid].s[0] = build(l, mid - 1, mid);
    if (r > mid)
        tr[mid].s[1] = build(mid + 1, r, mid);
    pushup(mid);
    return mid;
}

void rotate(int x)
{
    int y = tr[x].p, z = tr[y].p;
    pushdown(y), pushdown(x);//下传标记
    int k = tr[y].s[1] == x;
    tr[z].s[tr[z].s[1] == y] = x, tr[x].p = z;
    tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;
    tr[x].s[k ^ 1] = y, tr[y].p = x;
    pushup(y), pushup(x);
}

void splay(int x, int k)
{
    while (tr[x].p != k)
    {
        int y = tr[x].p, z = tr[y].p;
        pushdown(z), pushdown(y), pushdown(x);//提前下传标记
        if (z != k)
        { 
            if ((tr[y].s[1] == x) ^ (tr[z].s[1] == y))
                rotate(x);
            else
                rotate(y);
        }
        rotate(x);
    }
    if (!k)
        root = x;
}

int get_k(int k)
{
    int u = root;
    while (u)
    {
        pushdown(u);
        if (tr[tr[u].s[0]].siz >= k)
            u = tr[u].s[0];
        else if (tr[tr[u].s[0]].siz + 1 == k)
            return u;
        else
            k -= tr[tr[u].s[0]].siz + 1, u = tr[u].s[1];
    }
    return -1;
}

void reverse(int ll, int rr)
{
    int l = get_k(ll), r = get_k(rr + 2);
    splay(l, 0), splay(r, l);
    tr[tr[r].s[0]].lz ^= 1;
}

int main()
{
    int n;
    scanf("%d", &n);
    hi[1] = -INF, hi[n + 2] = INF;//下标从1开始
    for (int i = 2; i <= n + 1; i++)
        scanf("%d", &hi[i]);
    root = build(1, n + 2, 0);
    sort(poi + 1, poi + n + 3, cmp);
    for (int i = 2; i <= n + 1; i++)
    {
        int u = poi[i].second;
        splay(u, 0);
        int x = tr[tr[u].s[0]].siz + 1;
        printf("%d ", x - 1);
        reverse(i - 1, x - 1);
    }
    return 0;
}

标签:int,题解,P3165,tr,mid,siz,pushdown,CQOI2014,lz
来源: https://www.cnblogs.com/A2484337545/p/14361189.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有