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
原文地址:https://www.cnblogs.com/InitRain/p/12426671.html