CF1692G 2^Sort

2^Sort

题面翻译

给你一个长度为 n (n<2105) 的数组 a,问你在这个数组中,有多少个长度为 k+1 (1k<n) 的区间,符合以下的条件:

20ai<21ai+1<22ai+2<<2kai+k\footnotesizei

tzyt翻译

题目描述

Given an array a of length n and an integer k , find the number of indices 1ink such that the subarray [ai,,ai+k] with length k+1 (not with length k ) has the following property:

  • If you multiply the first element by 20 , the second element by 21 , ..., and the ( k+1 )-st element by 2k , then this subarray is sorted in strictly increasing order.

More formally, count the number of indices 1ink such that 20ai<21ai+1<22ai+2<<2kai+k.$$

输入格式

The first line contains an integer t ( 1t1000 ) — the number of test cases.

The first line of each test case contains two integers n , k ( 3n2105 , 1k<n ) — the length of the array and the number of inequalities.

The second line of each test case contains n integers a1,a2,,an ( 1ai109 ) — the elements of the array.

The sum of n across all test cases does not exceed 2105 .

输出格式

For each test case, output a single integer — the number of indices satisfying the condition in the statement.

样例 #1

样例输入 #1

6
4 2
20 22 19 84
5 1
9 5 3 2 1
5 2
9 5 3 2 1
7 2
22 12 16 4 3 22 12
7 3
22 12 16 4 3 22 12
9 3
3 9 12 3 9 12 3 9 12

样例输出 #1

2
3
2
3
1
0

提示

In the first test case, both subarrays satisfy the condition:

  • i=1 : the subarray [a1,a2,a3]=[20,22,19] , and 120<222<419 .
  • i=2 : the subarray [a2,a3,a4]=[22,19,84] , and 122<219<484 .

In the second test case, three subarrays satisfy the condition: - i=1 : the subarray [a1,a2]=[9,5] , and 19<25 .

  • i=2 : the subarray [a2,a3]=[5,3] , and 15<23 .
  • i=3 : the subarray [a3,a4]=[3,2] , and 13<22 .
  • i=4 : the subarray [a4,a5]=[2,1] , but 12=21 , so this subarray doesn't satisfy the condition.

思路:

主要是把公式好好思考一遍,从公式入手,分析前一项和当前项的关系,可以发现a[i]<2a[i+1],所以这道题是求连续区间的满足这个条件且满足区间长度为k+1的这个问题。那么求一段区间连续的和用前缀和来写,我们只要把符合a[i]<2a[i+1]这个条件视为正确1,不满足为0,从k个长度的区间来看,一定有k-1个数对是满足这个需求的。所以这道题主要用前缀和就能搞定。

代码:

#include<iostream>
using namespace std;
int main(){
    int t;cin>>t;
    while(t--){
        int n,x;cin>>n>>x;
        int a[n+1],s[n+1];
        for(int i=1;i<=n;i++){
            cin>>a[i];//读入数据
        }
        //开始前缀和的预处理
        for(int i=1;i<=n;i++){
            bool flag=0;
            if(a[i]<2*a[i+1]){
                flag=1;//为合法数量
            }
            s[i]=s[i-1]+flag;
        }
        int ans=0;
        //然后统计满足区间的数量
        //长度为k+1的区间,实质上满足条件的数对只存在k+1-1个,也就是k个。
        for(int i=1;i<=n-x;i++)
            if(s[i+k-1]-s[i-1]==x)//i+k-1为右端点,i为左端点,共有i+k-1-i+1=k个数
                ans++;
        cout<<ans<<endl;
    }
}

posted @   阿四与你  阅读(66)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
主题色彩