首页 > 其他分享 >分治初步

分治初步

时间:2024-05-18 15:51:46浏览次数:19  
标签:递归 好串 int 分治 mid 初步 ans cal

分治初步

归并排序求逆序对

Sol:在归并排序过程中,本身就是分治思想,递归的对左区间排序,右区间同理。对于已经有序两段进行合并只需要\(O(n)\)的时间,递归共\(log_{2}{n}\)层,时间复杂度为\(O(nlog_{2}{n})\)

debug:1.对于没有到达边界的一段也需要放入临时数组,并且继续统计答案

2,先审核一遍代码,出现了没有调用函数,只打个括号的情况,没有报错,需要注意

int solve(int l,int r){
	if(l==r)return 0;
	int mid=(l+r)>>1;
	int res=solve(l,mid)+solve(mid+1,r);
	int pl=l,pr=mid+1;
	int cnt=0;
	while(pl<=mid&&pr<=r){
		if(a[pl]<=a[pr]){
			c[++cnt]=a[pl++];
			res+=pr-1-(mid+1)+1;
			}
		else {
			c[++cnt]=a[pr++];
		}
	}
	//还需要处理没到边界的一侧
	while(pl<=mid){c[++cnt]=a[pl++];res+=pr-(mid+1);}
	while(pr<=r)c[++cnt]=a[pr++];
	int k=1;
	for(int i=l;i<=r;i++)a[i]=c[k++];
	return res;
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	int ans=solve(1,n);
	//for(int i=1;i<=n;i++)cerr<<a[i]<<" ";
	cout<<ans<<endl;
}

Codeforces Round 656 (Div. 3) D

a-Good String

定义:字符串s 为一个c-好串(c 为一个字符)时,必须满足:

  1. 当\(|s| = 1\) ,\(s = c\)

  2. 当\(|s| > 1\), \(s\) 的左半部分为全为 \(c\),右半部分为一个 (c+1)-好串 或者 \(s\) 的右半部分为全为 \(c\),左半部分为一个 (c+1)-好串

其中 \(|s|\) 代表 字符串 \(s\) 的长度。

举个例子:当 \(s=“cdbbaaaa"\)时,\(s\) 是一个 a-好串

现在,给你一个字符串 \(s\) ( \(|s| = 2^k\) ),问最少替换多少个字符,使其为一个 a-好串

Sol:注意题目给出的字符串长度是特殊的,结合题目意思是非常明显的递归求解暗示。每轮中我们只需要决策是选择前半段作为当前轮字母对应段还是后半段。选择以后,另一段的代码递归求解即可,注意递归边界处理。

string s;
int cal(int l,int r,int lev){
	int res=0;
	char c=lev+'a';
	if(l==r){
		if(s[l]==c)return 0;
		return 1;
	}
	int mid=(l+r)>>1;
	int c1=0,c2=0;
	
	for(int i=l;i<=mid;i++)if(s[i]!=c)c1++;
	for(int i=mid+1;i<=r;i++)if(s[i]!=c)c2++;
	res=min(c1+cal(mid+1,r,lev+1),c2+cal(l,mid,lev+1));
	return res;
}
void solve(){
	cin>>n;
    cin>>s;
	s=" "+s;
	int ans=cal(1,n,0);
	cout<<ans<<endl;
}

平面最近点对https://www.luogu.com.cn/problem/P1429

P7883 平面最近点对(加强加强版)
给定平面上 \(n\) 个点,找出其中的一对点的距离,使得在这 \(n\) 个点的所有点对中,该距离为所有点对中最小的
数据保证 \(0\le x,y\le 10^9\)

Sol:本题存在\(O(nlogn)\)的解法,对于排序的复杂度采用归并y来降低https://www.luogu.com.cn/article/aihyptbk,这里先给出朴素的\(O(n(log_{}{n})^2)\)做法

整体思路:以x大小为分界线进行分治,左边内部的最近点对递归解决,右边同理。对于左右交界的贡献,首先考虑横坐标距离分界线大于d无法更新答案,对于这些点按y排序,对于其中一个点,纵坐标距离大于d也不可能更新,可以证明一个点可以用来更新答案的点不超过6个(只考虑中坐标比自己大的点,偏序不重复)。

struct node{
	db x,y;
	bool operator<(const node &A)const{
		return x<A.x;
	}
}a[N],c[N];
db dis(node c,node d){
    db c1=c.x-d.x,c2=c.y-d.y;
    return sqrt(c1*c1+c2*c2);
}
db cal(int l,int r){
	if(l==r)return 1e12;
	int cnt=0;int mid=(l+r)>>1;
	db d=min(cal(l,mid),cal(mid+1,r));
	for(int i=l;i<=r;i++){
		if(fabs(a[i].x-a[mid].x)<d){
			c[++cnt].y=a[i].x;
			c[cnt].x=a[i].y;
		}
	}
	sort(c+1,c+1+cnt);
	for(int i=1;i<=cnt;i++){
		for(int j=i+1;j<=cnt&&fabs(c[j].y-c[i].y)<d;j++){
			d=min(d,dis(c[i],c[j]));
		}
	}
	return d;
}
void solve(){
	//cerr<<18*18*N<<endl;
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;
	sort(a+1,a+1+n);
	db  ans=cal(1,n);
	baoliu(ans,4);
}

标签:递归,好串,int,分治,mid,初步,ans,cal
From: https://www.cnblogs.com/mathiter/p/18199395

相关文章

  • 分治思想求众数_虽然效率不好_但是便于学习分治的思想方法
    //解释:/*采用分治法的思想在这道题中的体现就是对于一个区间去分成两份,然后count函数的作用是对于一个区间段的函数去进行统计某个数的个数find函数的作用是负责把区间分开,然后对比两个区间中的出现次数更多的数,把这个数作为这两个区间合成的区间的众数。对比的依据就是count......
  • 点分治
    点分治树的重心(前置芝士)如果在树中选择某个节点并删除,这棵树将分为若干棵子树,统计子树节点数并记录最大值。取遍树上所有节点,使此最大值取到最小的节点被称为整个树的重心。性质树的重心如果不唯一,则至多两个且相邻以树的重心为根时,所有子树的大小都不超过整棵树大小的......
  • elasticsearch初步使用学习
    通过使用elasticsearch,我们可以加快搜索时间(直接使用SQL的模糊查询搜索耗时会比较久,而且elasticsearch的响应耗时与数据量关系不大)es主要用于存储,计算,搜索数据依次部署elasticsearch,kibanadockerrun-d\--namees\-e"ES_JAVA_OPTS=-Xms512m-Xmx512m"\-e"disco......
  • 关于浏览器插件的初步认识
    1.浏览器插件是什么,如何安装?它是浏览器允许添加额外功能或修改其行为的软件组件。这些拓展通常由第三方开发者创建,并通过浏览器的拓展系统进行安装和管理。不同浏览器有不同的拓展系统,例如:Chrome拓展:Chrome使用ChromeWebStore来分发和管理拓展。用户可以通过访问Chro......
  • 【DP】【分治】最大子数组和
    题源不要太激动,过拟合,一上来就开dp,这道题只用一个变量就可以记录前缀和了【转载】我觉得这道题目的思想是:走完这一生如果我和你在一起会变得更好,那我们就在一起,否则我就丢下你。我回顾我最光辉的时刻就是和不同人在一起,变得更好的最长连续时刻classSolution:defmaxSu......
  • cdq 分治
    1概念cdq分治,是一种分治思想而非具体算法。它是基于分治思想,将复杂的问题拆分求解。与一般分治算法不同的是,一般分治所拆分的子问题互相独立、互不干扰、形式与原问题一致。而在cdq分治中,每次划分出的两个子问题,是利用前面的子问题解决后面的子问题。也就是说,对于序列\([l,......
  • CF-797-E-根号分治
    797-E题目大意给定一个长为\(n\)序列\(a\),有\(q\)次询问:给定\(p,k\),你需要反复执行操作\(p=p+a_p+k\),直到\(p>n\)为止,问你要执行多少次操作。Solution考虑两种思路:1、暴力回答询问,每次反复模拟操作,直到\(p>n\)为止,时间复杂度\(O(q·\frac{n}{k})\)。2、预处理出......
  • 点分治
    点分治本质就是树上的分治。序列的分治是不断地将序列二分,而对于树则需要利用树的重心。树的重心定义:树中一节点,以它为根的最大的子树最小。求解:跑一遍\(dfs\)求解即可。voidget_rt(intu,intfa){ siz[u]=1,max_siz[u]=0; for(autov:T[u]){ if(v.fir==fa|......
  • GitHub Copilot 初步
    1.概述GitHubCopilot是一款AI编码助手,可帮助我们更快、更省力地编写代码,从而将更多精力集中在问题解决和协作上。Copilot会在你键入时提供编码建议:有时是当前行的补全,有时是全新的代码块。可以接受全部或部分建议,也可以忽略建议并继续键入。使用聊天功能,可以询问Copilot......
  • 洛谷2664树上游戏-点分治
    link:https://www.luogu.com.cn/problem/P2664lrb有一棵树,树的每个节点有个颜色。给一个长度为\(n\)的颜色序列,定义\(s(i,j)\)为\(i\)到\(j\)的颜色数量。以及\[sum_i=\sum_{j=1}^ns(i,j)\]现在他想让你求出所有的\(sum_i\)。一个暴力的想法:因为是求和,所以可以拆......