ICode9

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

甜甜圈

2021-09-17 22:34:50  阅读:169  来源: 互联网

标签:甜甜 样例 指针 移动 最大值 define


跳转链接

题意

艾洛喜欢吃甜食,他有n个甜甜圈,现在叠成了两叠(如下图所示),第一叠有n1个,第二叠有n2个(n1+n2=n),要解决的问题如下:

  • 每个甜甜圈都有一个唯一的甜度值\(s_i\)
  • 甜度值两两不同;
    每次艾洛可以把任意一叠位于顶端的一个甜甜圈移动到另一叠顶端,若该甜甜圈是当前所有甜甜圈中最甜的(甜度值最大),那么艾洛不会移动甜甜圈,而是直接吃掉;
    请你求出艾洛吃完所有甜甜圈的最小移动步数;

题目样例

样例输入
3 3
1 4 5
2 7 3
样例输出
6

思路

我们可以把两叠甜甜圈从顶端拼接成一个甜甜圈.
问题就转化为了按照从大到小的顺序去移动一个指针(指针的初始点在两个甜甜圈的顶端位置)
这个问题可以用树状数组解决

我们模拟一下样例
3 7 2 | 1 4 5 (刚开始的时候指针在中间)
3 | 2 1 4 5 然后指针要移动到最大值(7) 移动了 一次
3 2 1 4 | 然后指针要移动到最大值(5) 移动了 三次
3 2 1 | 然后指针要移动到最大值(4) 移动了 零次
| 2 1 然后指针要移动到最大值(3) 移动了 两次
| 1 然后指针要移动到最大值(2) 移动了 零次
| 然后指针要移动到最大值(1) 移动了 零次

因此呢,问题就转化为了求从最大值到最小值按顺序移动最少需要移动多少次的问题
我们只需要对数组按照大小排一下序,然后用树状数组求得即可

CODE

#include <cstdio>
#include <algorithm>
#define LL long long
#define lowbit(x) x & -x
#define fi first
#define se second
#define PII pair<int, int>

using namespace std;

const int N = 1e5 + 10;

int n, m, len, tr[N];
PII a[N];

inline void add(int x, int c) {
    while(x <= len) {
        tr[x] += c;
        x += lowbit(x);
    }
}

inline int ask(int x) {
    int res =  0;
    while(x) {
        res += tr[x];
        x -= lowbit(x);
    }
    return res;
}


int main() {
    scanf("%d%d", &n, &m); len = n + m;

    for(int i = m + 1; i <= len; i ++ ) {
        int x; scanf("%d", &x);
        add(i, 1);
        a[i] = {x, i};
    }
    for(int i = m; i; i -- ) {
        int x; scanf("%d", &x);
        add(i, 1);
        a[i] = {x, i};
    }
    sort(a + 1, a + 1 + len);
    reverse(a + 1, a + 1 + len);
    a[0].se = m;
    LL ans = 0;
    for(int i = 1; i <= len; i ++ ) {
        add(a[i].se, -1);
        //这里先把它减少就可以避免一个小问题 如果指针和当前的最大值相邻的话,就直接不用考虑移动了
        ans += abs(ask(a[i].se) - ask(a[i-1].se));
    }
    printf("%lld\n", ans);

    return 0;
}

标签:甜甜,样例,指针,移动,最大值,define
来源: https://www.cnblogs.com/c972937/p/15306572.html

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

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

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

ICode9版权所有