首页 > 其他分享 >Binary Deque(二分)

Binary Deque(二分)

时间:2024-12-03 17:32:27浏览次数:15  
标签:二分 Binary Deque int sum leq test array define

Slavic has an array of length \(n\) consisting only of zeroes and ones. In one operation, he removes either the first or the last element of the array.

What is the minimum number of operations Slavic has to perform such that the total sum of the array is equal to \(s\) after performing all the operations? In case the sum \(s\) can't be obtained after any amount of operations, you should output -1.

Input

The first line contains a single integer \(t\) (\(1 \leq t \leq 10^4\)) — the number of test cases.

The first line of each test case contains two integers \(n\) and \(s\) (\(1 \leq n, s \leq 2 \cdot 10^5\)) — the length of the array and the needed sum of elements.

The second line of each test case contains \(n\) integers \(a_i\) (\(0 \leq a_i \leq 1\)) — the elements of the array.

It is guaranteed that the sum of \(n\) over all test cases doesn't exceed \(2 \cdot 10^5\).

Output

For each test case, output a single integer — the minimum amount of operations required to have the total sum of the array equal to \(s\), or -1 if obtaining an array with sum \(s\) isn't possible.

题义: 给一个 01 串 ,长度为 n, 只能从头或者尾部删除 , 问最少删除多少次 , 使得剩下的元素和为 s

思路:
从每一个起始位置开始遍历, 对于每一个起始位置, 二分法找到他的对应的最长终止位置.

#include<bits/stdc++.h>
#define L(i, j, k) for(int i = (j); i <= (k); ++i)
#define R(i, j, k) for(int i = (j); i >= (k); --i)
#define sz(a) ((int) (a).size())
#define pb emplace_back
#define me(a, x) memset(a, x, sizeof(a))
#define vi vector<int>
#define ull unsigned long long
#define i128 __int128
#define TEST 
#define TESTS int T; cin >> T; while(T--)
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long
const int N = 1E+6;
using namespace std;
void Main() {
	int n ,s;
	cin >> n >> s;
	vi a(n+1);
	cin >> a[1];
	L(i, 2, n) { // 前缀和
		int num;
		cin >> num;
		a[i] = a[i-1] + num;
	}
	int ans = INF;
	L(i, 1, n) { // 枚举起始点, 二分找终点
		int lo = i, hi = n; // 在 i 到 n 的范围内二分
		while(lo <= hi) { //当 lo == hi 时 ,可能出现区间长度正好比 k 多一 ,所以写 小于等于 多判断一次
			int mid = lo + ((hi - lo) >> 1);
			if(a[mid] - a[i - 1] <= s) { // 数组从 i 到 mid 的和不大于 k, 向上查找更长的
				lo = mid + 1;
			}
			else { // 若区间长度正好比 k 多一  hi-- ,返回 hi
				hi = mid - 1;
			}
			//cout << "i= " << i << "   " << "lo= " << lo << "    hi= " << hi << endl;
		}
		if(a[hi] - a[i - 1] != s) continue;
		ans = min(ans, n - hi + i - 1); // 答案是总长度减去最长的区间的长度
	}
	cout << (ans == INF ? -1 : ans) << endl;
}
signed main() {
	ios :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	TESTS Main();
	return 0;
}

标签:二分,Binary,Deque,int,sum,leq,test,array,define
From: https://www.cnblogs.com/shen-kong/p/18584602

相关文章

  • 502 二分答案
    //502二分答案.cpp:此文件包含"main"函数。程序执行将在此处开始并结束。///*http://oj.daimayuan.top/course/22/problem/61给一个序列a1,a2,…,an。你可以对这个序列进行操作,每次操作可以选择一个元素,把它加1,经过不超过k次操作之后,希望序列里面的最小值最大......
  • 二分查找
    [Algo]二分查找注:Algo系列基于左神算法教程,提供C++实现。1.经典算法//1.经典二分查找:给定有序序列,查找val,存在返回(任一)索引,否则返回-1intbinarySearch(constvector<int>&v,intval){if(v.size()==0)return-1;intleft=0,right=v.size()-1,m......
  • Java入门:21.System类,Runtime类,Arrays类的常用方法,二分查找算法
    1System类System.exit(0); //手动关闭应用程序​System.currentTimeMillis();//获得当前系统时间的毫秒数​System.out;//获得一个打印流,可以实现控制台打印System.out.print();//打印内容(不换行)System.out.println();//打印内容,并换行System.out.printf();//......
  • Java面试要点54 - Java List的二分查找算法
    文章目录一、引言二、二分查找的基本原理三、JavaCollections工具类中的二分查找四、自定义比较器的二分查找实现五、处理特殊情况六、性能优化与最佳实践七、总结一、引言在Java程序开发中,查找操作是一个非常基础且关键的算法需求。其中,二分查找(BinarySearch)......
  • 【二分查找】力扣 275. H 指数 II
    一、题目二、思路h指数是高引用引用次数,而citations数组中存储的就是不同论文被引用的次数,并且是按照升序排列的。也就是说h指数将整个citations数组分成了两部分,左半部分是不够引用h次的论文,右半部分论文的引用次数都是大于等于h的。因此,可以采用二分查找的......
  • 二分图
    定义对于一张无向图\(G\),若所有点可以分为两个点集\(A\)和\(B\),且\(A\)和\(B\)的内部没有连边,那么我们称\(G\)可以划分为一张二分图。二分图的划分不唯一,也不一定联通,也不一定有环存在的充要条件若无向图\(G\)是二分图,那么\(G\)没有奇环。若无向图\(G\)没......
  • C#里怎么样使用Array.BinarySearch函数?
    C#里怎么样使用Array.BinarySearch函数?因为二分算法如此重要,所以要多加练习。但是它的返回值,也有三种状态,导致很多人使用它的时候,也感觉到迷惑的。在这里的例子演示了三种返回值的使用: /**C#ProgramtoSearchanelementwithArrayIndices*/usingSystem;c......
  • 【C++算法】21.二分查找算法_山脉数组的峰顶索引
    文章目录题目链接:题目描述:解法C++算法代码:图解题目链接:852.山脉数组的峰顶索引题目描述:解法暴力解法:若:arr=[0,1,2,3,2,1,0]可以定义一个指针指向第一个元素,如果它后面的元素比它大,那么他就不是峰值。当第一次遇到一个数是大于后面那个数的时候,那个数就......
  • 【C++习题】22.二分查找算法_寻找峰值
    文章目录题目链接:题目描述:解法C++算法代码:图解题目链接:162.寻找峰值题目描述:解法暴力解法:三种山峰的情况开始元素比它后面一个元素大的话直接就是山峰了(因为nums[-1]=nums[n]=-∞)普通山峰最后一个元素比前面一个元素大的话直接就是山峰了二分算......
  • 24/11/30 ABC381+莫队+分块+整体二分学习笔记
    [ABC381D]好题。由于题目描述中提到了取出的子序列长度必须是偶数个,所以可以考虑对于原来的\(a\)序列每次进行长度为\(2\)的尺取,这时候不难发现对于开头位置具有两个答案,一个是从\(1\)为开头,一个是从\(2\)为开头,所以写个函数封装一下就好了,类似这种cout<<max(solve(1),solve(2......