zoukankan      html  css  js  c++  java
  • cf 1237 D. Balanced Playlist(单调队列+二分)(好题)

    题意:

    有n首音乐,每首音乐都有一个值ai,从第i首开始,列表循环播放,当前播放的所有音乐中的最大值计为mx,如果下一首音乐的值*2  < mx,那么,终止播放。

    问:依次从每一首开始播放,各可以播放几首?

    思路:

    这题我是看了题解才会的,果然还是菜呀。

    对于i,我们找1~(i-1)中,最靠近 i 的 j ,使得ai * 2 < aj,这一步用单调队列+二分来做。

    找到 j 以后,就可以更新 j 的答案了,用min,就是看 如果从 j 开始的话(mx就是为a,先不考虑 j 后面的点)最快到哪里会停下。

    但是mx是会变的,所以从后扫回来,min一下。

    结束。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <cmath>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    typedef long long int ll;
    const double pi = acos(-1);
    const int maxn = 3e5 + 10;
    const int inf = 0x3f3f3f3f;
    int qu[maxn],a[maxn],n,mi[maxn],head,tail,ans[maxn];
    void _push(int pos)
    {
        while(head <= tail && a[pos] >= a[qu[tail]]){
            tail--;
        }
        qu[++tail] = pos;
    }
    int get_pos(int u)
    {
        int l = head,r = tail,mid,res = -1;
        while(l <= r){
            mid = (l + r) >> 1;
            if(a[qu[mid]] > a[u] * 2){
                res = mid;
                l = mid + 1;
            }
            else
                r = mid - 1;
        }
        if(res == -1)
            return -1;
        return qu[res];
    }
    int main()
    {
        while(scanf("%d",&n) != EOF){
            head = 0;
            tail = -1;
            memset(mi,inf,sizeof(mi));
            int _mi = 1e9,_mx = 0;
            for(int i = 1;i <= n;i++){
                scanf("%d",&a[i]);
                _mi = min(_mi,a[i]);
                _mx = max(_mx,a[i]);
                a[n + i] = a[2 * n + i] = a[i];
            }
            n = 3 * n;
            if(!(_mx > _mi * 2)){
                for(int i = 1;i <= n / 3;i++)
                    printf("-1 ");
                puts("");
                continue;
            }
            int temp;
            for(int i = 1;i <= n;i++){
                _push(i);
                temp = get_pos(i);
                if(temp == -1)
                    continue;
                
                mi[temp] = min(mi[temp],i);
            }
            _mi = 1e9;
            int res;
            for(int i = n;i >= 1;i--){
                res = min(_mi,mi[i]);
                ans[i] = res;
                _mi = min(_mi,mi[i]);
            }
            for(int i = 1;i <= n / 3;i++)
                printf("%d ",ans[i] - i);
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    [docker]Kubernetes的yaml文件
    [redis]redis-cluster的使用
    [redis]redis-cluster搭建
    [docker]本地仓库的创建的使用
    1W字看懂互联网知识经济
    PHP基础陷阱题(变量赋值)
    PHP不用第三变量交换2个变量的值的解决方法
    PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
    PHP实现四种基本排序算法
    WEB安全之Token浅谈
  • 原文地址:https://www.cnblogs.com/InitRain/p/12426671.html
Copyright © 2011-2022 走看看