codeforces D. Balanced Playlist

思维题

我现在非常喜欢的题(因为之前被思维题弄死了。

虽然这次没想出来,看了题解才会的。
其实非常简单,只需要掌握一个核心思想:

假如 i i i最远能到 j j j,那么 i + 1 i+1 i+1最远起码到 j j j
因为 i + 1 i+1 i+1开始的前缀最大值会更小,就更能走的更远,起码到 j j j

并且,如果走的长度是有限的话,是不会超过 2 n 2n 2n的,因为第一遍刚得到最值,可能后面的最大值会让前面的不满足要求,所以再跑一点才会不合法,最多是 2 n 2n 2n的,应该是到不了 2 n 2n 2n否则就是无限了。

我们化环为链即可。对于区间最值可以用 S T ST ST表快速做,(单调队列应该也可以做。
具体处理是 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
using namespace std;
vector<int> v;

typedef long long ll;
const int maxn = 3e5+500;

#define maxk 21
int st[maxn][maxk];
int p[maxn],a[maxn],tmp,n;

void ST_init(){
    for(int i=1;i<=n;i++){
        st[i][0]=a[i];
    }
    for(int j=1;(1<<j)<=n;j++){
        for(int i=1;i<=n;i++){
            st[i][j]=max(st[i][j-1],st[min(n,i+(1<<(j-1)))][j-1]);
        }
    }
    p[0]=-1;for(int i=1;i<=n;i++)p[i]=p[i>>1]+1;
}

inline int getmax(int l,int r){
    int t=p[r-l+1];
    return max(st[l][t],st[r-(1<<t)+1][t]);
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a[n+i]=a[i];
        a[2*n+i]=a[i];
    }
    n*=3;
    ST_init();
    int now=0;
    for(int i=1;i<=n/3;i++){
        int j=now;
        while(j<n){
            if(getmax(i,j+1)<=2*a[j+1]){
                j++;
            }
            else break;
        }
        now=j;
        int ans=now-i+1;
        if(now==n)ans=-1;
        printf("%d%c",ans,i==n/3?'\n':' ');
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值