首页 > 其他分享 >D-二分

D-二分

时间:2024-08-27 22:48:11浏览次数:5  
标签:二分 int 括号 maxn ls ql

最近做了一个CFround166的d题然后发现我并不会二分(虽然标答并不是二分)。故来写一下。

题目:https://codeforces.com/contest/1976/problem/D

首先观察到几个显而易见的性质:

1.若要翻转[l,r],[l,r]中的(和)数量相等

2.为了能和前面匹配上,翻转后[l,r]中未匹配右括号的(最大)数量要等于[1,l-1]中未匹配左括号的数量。

好的到这里我就不会了。但是如果考虑左括号比右括号多的数量并且把每个位置的值设为{a_i},那么就可以实现这两个性质的量化(这一步真的想不到,感觉数学思维要加强,其实有点像一个入栈出栈的操作吧。

1.\({a_{l-1}==a_r}\)

2.\({a_{l-1}>=a_i-a{l-1}}\)(最大未匹配的右括号不能多于未匹配的左括号),可变形简化为\(a_{l-1}*2>=a_i\)

那么我们想如果固定l-1,r的取值一定是l-1右边连续的一个范围,因为有一个不满足的显然右边所有点都不满足。

我:这个不能二分,因为二分要在有序的序列上进行。 佬:答案具有单调性就可以二分。

然后我想了一下用线段树维护mx的话确实是可以二分的。所以写完了。

#include<bits/stdc++.h>
using namespace std;
#define ls(x) (x<<1)
#define rs(x) ((x<<1)+1)
#define mid ((l+r)>>1)
#define int long long
const int mod=1e9+7;
const int maxn=2e5+10;

int sta[maxn],pos[maxn]; 
int t[maxn*4];
vector<int>E[maxn];

void build(int x,int l,int r){
	if(l==r){
		t[x]=sta[l];return;
	}
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	t[x]=max(t[ls(x)],t[rs(x)]);
}
int	que(int x,int ql,int qr,int l,int r){
	if(l>=ql&&r<=qr){
		return t[x];
	}
	int res=0;
	if(mid>=ql)res=que(ls(x),ql,qr,l,mid);
	if(mid<qr)res=max(res,que(rs(x),ql,qr,mid+1,r));
	return res;
}

void solve(){
	string s;cin>>s;
	for(int i=0;i<=s.size();i++)E[i].clear(),pos[i]=0;
	for(int i=0,w=0;i<s.size();i++){
		if(s[i]=='(')w++;
		else w--;
		sta[i+1]=w;
		E[w].push_back(i+1);
		pos[i+1]=E[w].size()-1;
	}
	int n=s.size(),ans=0;
	build(1,1,n);
	//cout<<1;
	for(int i=1;i<s.size();i++){
		int l=i+1,r=n,mid1=(l+r+1)>>1;
		while(l<r){
			if(que(1,l,mid1,1,n)<=sta[i]*2){
				l=mid1;
			}
			else r=mid1-1;
			mid1=(l+r+1)>>1;
		}
		int w=sta[i];
		l=0,r=E[w].size()-1;
		int mid2=(l+r+1)>>1;
		while(l<r){
			if(E[w][mid2]<=mid1)l=mid2;
			else r=mid2-1;
			mid2=(l+r+1)>>1;
		}
		ans+=mid2-pos[i];
	}	
	cout<<ans<<endl;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int tt;cin>>tt;while(tt--){
		solve();
	}	
	
}

标签:二分,int,括号,maxn,ls,ql
From: https://www.cnblogs.com/lyrrr/p/18383692

相关文章

  • 二分查找
    1.基础版publicintsearch(int[]nums,inttarget){inti=0,j=nums.length-1;while(i<=j){intmiddle=(i+j)>>>1;if(target<nums[middle]){j=middle-1;......
  • 二分查找算法:朴素二分+左右边界二分&力扣实战应用
    目录:1、二分查找算法简介2、算法原理及时间复杂度分析2.1朴素二分算法3.2查找左右边界的二分算法3.2.1查找左边界3.2.2查找右边界3.3时间复杂度分析3、二分查找算法模版3.1朴素二分模版3.2查找左右边界的二分模版4、算法应用【leetcode】4.1题一:搜素插入位......
  • 浅谈二分算法
    浅谈二分算法二分首先知道一下二分是什么。二分,是一种快速处理大型数据的方法。基本逻辑是折半查找。设有一个共有\(n\)个数字的数组,要从中查询某个元素,就可以用二分查找。注:这里的数组默认其成员数值具有单调性。这个点十分重要。还记得小时候(我现在才新初一)跟同学玩过一......
  • 8.26下午二分与深搜测试
    8.26下午二分与深搜测试比赛传送门分数情况P2249【深基13.例1】查找P1706全排列问题P8647[蓝桥杯2017省AB]分巧克力P2440木材加工B3624猫粮规划P2105K皇后P3853路标设置P3743小鸟的设备01001210000015T1.P2249【深基13.例1】查找题......
  • 《机器学习》—— 随机森林实现二分类问题
    文章目录一、什么是随机森林二、随机森林的主要特点三、随机森林参数四、案例的代码实现一、什么是随机森林随机森林(RandomForest)是一种集成学习方法,属于监督学习算法,主要用于分类和回归任务。它通过在数据集的多个子集上构建多个决策树,并输出这些树预测结果的众数(......
  • 【Kaggle】练习赛《有毒蘑菇的二分类预测》(下)
    前言上篇《有毒蘑菇的二分类预测》(上)用ColumnTransformer和Pipeline技术来提升缺失值和建模的方法,本篇将用特征工程的方法,将特征扩展,由原先的21个特征扩展成118个特征,再用深度学习的方法进行建模以达到较好的成绩,同时,在这篇里增加了上篇没有EDA部分,更好的展示数据集......
  • 信息学奥赛初赛天天练-75-NOIP2016普及组-完善程序-二分答案、二分查找、贪心算法、贪
    1完善程序(单选题,每小题3分,共30分)郊游活动有n名同学参加学校组织的郊游活动,已知学校给这n名同学的郊游总经费为A元,与此同时第i位同学自己携带了Mi元。为了方便郊游,活动地点提供B(≥n)辆自行车供人租用,租用第j辆自行车的价格为Cj元,每位同学可以使用自己携带的钱或......
  • 浅谈二分图
    定义二分图,又称二部图,英文名叫Bipartitegraph。二分图是什么?节点由两个集合组成,且两个集合内部没有边的图。换言之,存在一种方案,将节点划分成满足以上性质的两个集合。性质如果两个集合中的点分别染成黑色和白色,可以发现二分图中的每一条边都一定是连接一个黑色点和一个白......
  • 整体二分
    前置知识:二分,一些数据结构如树状数组用途:用于解决多次可二分可离线的询问。可以使用整体二分解决的题目应具有以下性质:询问的答案具有可二分性。修改对判定答案的贡献互相独立,修改之间互不影响效果。修改如果对判定答案有贡献,则贡献为一确定的与判定标准无关......
  • wqs 二分学习笔记
    蒟蒻的第一篇学习笔记qwqwqs二分用于解决此类问题n个物品,从中选恰好m个,最大化收益。而且你发现,如果没有选m个的限制,这道题是非常好做的。使用前提1、恰好选k个,至多至少不行2、答案满足凸性什么是凸性?设选i个物品时的收益为fi如果把它画成函数,那么它长这样(上凸包)或者这样......