[cf] 799 div4 G. 2^Sort

前言

t a g : tag : tag: 贡献 连续子段的合法情况 滑动窗口 思维
传送门 :

题意 :
给定 n , k n,k n,k,同时给定一个数组 a [ N ] a[N] a[N] , 询问数组中有多少个连续字段满足
2 0 a i < 2 1 a i + 1 < . . . . < 2 k a i + k 2^0a_i<2^1a_{i+1}<....<2^ka_{i+k} 20ai<21ai+1<....<2kai+k

思路 :
我们考虑对 单独一个 i i i 进行考虑,如果 a i < 2 ∗ a i + 1 a_i<2*a_{i+1} ai<2ai+1

那么显然这个值对前面的数是合法的,我们考虑将其贡献设置为 1 1 1

显然,对于一个 [ i . . . i + k ] [i...i+k] [i...i+k]的子段,如果其 贡献的累积是 k k k 的话,就说明都符合条件,因此这样会对所求答案贡献 + 1 +1 +1

因为是连续子段,我们只需要 顺着枚举一下长度为 k + 1 k+1 k+1的区间即可

我们可以才用 加入队尾,弹出队头的操作,维护该长度的区间

code :

int n,k;
int a[N];
int st[N];

void solve(){
	cin>>n>>k;
	//for(int i=1;i<=n;i++) st[i] = 0;
	
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<n;i++){
		st[i] =  (a[i] < 2*a[i+1]);
	}
	
	int tot = 0 ;
	
	for(int i=1;i<=k;i++){
		tot+=st[i];
	}
	
	int res = 0 ;
	if(tot == k) res++;
	
	for(int i = k+1 ; i <  n; i ++ ){
		tot += st[i];
		tot -= st[i-k];
		
		if(tot == k) res++;
	}
	
	cout<<res<<endl;
	
	
}

int main(){
    int t;cin>>t;while(t--)
    solve();
    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值