首页 > 其他分享 >最长的Y题解

最长的Y题解

时间:2024-10-25 15:10:25浏览次数:5  
标签:参照 int 题解 sum 转移 200100 最长

考虑将 Y 单独拎出来,用数组存储他的下标,那么将第 \(x\) 个 Y 转移至第 \(y\) 个 Y 就需要
\(a[x]-b[y]-1\) 次操作。

发现一个问题:

第一次从左移动至 \(y\) 需要减1,第二次从左移动需要减2……

如图:

image 这似乎是一个很麻烦的问题,我们的某知名 \(lyh\) 教授是通过指针(应该是吧)解决的。

但我有一个想法:

假若被转移点和参照点的路径中有别的 Y ,那么因为为了保证最优性,在被转移点左边的点必须先被转移!

听起来有点绕,上图!

image

那么就可以直接用被转移点前面的 Y 的个数减参照点前面 Y 的个数即可算出应该减多少了:

此部分代码处理:

for(int i=0;i<t.size();i++){
	if(t[i]=='Y'){
		a[++n]=i-n;
		sum[n]=sum[n-1]+a[n];
	}
}

接下来不难发现,经过我们巧妙的处理之后,我们将问题转换成了:

给定一个单调不降的序列,可以对其中的数+1或-1(对应着向左或向右交换)求 \(k\) 次操作后最多有几个数一样。

接下来又很容易想到:为了保证最优,一样的数一定是连续的,双(又+又)很容易想到,让连续的一段数一样的最优参照点一定是中位数。

令 \(i\) 为区间起点,\(x\) 为长度,\(sum\) 为前缀和,则转移需要的步数=

\[a[i+x/2]*(x/2)-(sum[i+x/2]-sum[i-1])+\\(sum[i+x-1]-sum[i+x/2-1])-a[i+x/2]*((x-1)/2) \]

image

这部分的代码处理:

for(int i=1;i<=n-x+1;i++){
	if((a[i+x/2]*(x/2)-(sum[i+x/2]-sum[i-1])+(sum[i+x-1]-sum[i+x/2-1])-a[i+x/2]*((x-1)/2))<=k){
		return 1;
	}
}

然后叒很容易想到,二分长度,枚举起点即可。

最后叕可以发现,时间复杂度 \(O(n\log n)\)。

ACcode

#include<bits/stdc++.h>
using namespace std;
string t;
int k,a[200100],n,sum[200100];
bool check(int x){
	for(int i=1;i<=n-x+1;i++){
		if((a[i+x/2]*(x/2)-(sum[i+x/2]-sum[i-1])+(sum[i+x-1]-sum[i+x/2-1])-a[i+x/2]*((x-1)/2))<=k){
			return 1;
		}
	}
	return 0;
}
signed main(){
	cin>>t>>k;
	for(int i=0;i<t.size();i++){
		if(t[i]=='Y'){
			a[++n]=i-n;
			sum[n]=sum[n-1]+a[n];
		}
	}
	int l=0,r=n;
	while(l<=r){
		int mid=(l+r)/2;
		if(check(mid)){
			l=mid+1;
		}
		else{
			r=mid-1;
		}
	}
	cout<<r<<endl;
}

标签:参照,int,题解,sum,转移,200100,最长
From: https://www.cnblogs.com/lewisak/p/18502596

相关文章

  • 家谱树题解
    (ACM比赛时忘了拓扑怎么写时代尻古)假设有一个DAG图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:1.从DAG图中选择一个没有前驱(即入度为0)的顶点并输出。2.从图中删除该顶点和所有以它为起点的有向边。3.重复1和2直到当前的DAG图为空或当前图中不存在无前驱的......
  • SSL证书常见问题解答
    在当今的数字时代,确保网站和数据的安全性变得尤为重要。SSL(SecureSocketsLayer)证书作为保障网站安全的关键组件,广泛应用于各种在线服务中。然而,在SSL证书的申请、安装和使用过程中,用户常常会遇到各种问题。本文旨在提供一个全面的指南,帮助用户理解并解决SSL证书的常见问题。......
  • 题解:CF722D Generating Sets
    涉及知识点:set。解题思路每次让列表中最大的元素缩小两倍,保证答案最优。如果当前的元素缩小成$0$就直接跳出循环,输出这个序列。由于序列需要支持插入、删除以及找最大值,所以这个序列可以用set来维护。代码#include<bits/stdc++.h>#defineintlonglong#definell......
  • 题解:P10298 [CCC 2024 S4] Painting Roads
    涉及知识点:图的遍历。我们观察样例可以发现,染色之后的图是一颗树,而且还是dfs树。题目要求所以路径上的颜色都是交替的,所以直接交替染色即可。注意:建图的时候需要记录当前边的编号。代码#include<bits/stdc++.h>#defineintlonglong#definell__int128#definedbd......
  • 题解:SP25334 NPC2015A - Eefun Guessing Words
    涉及知识点:字符串处理。解题思路记录每个字符出现的第$1$个位置和最后$1$个位置,询问时比较大小即可。代码#include<bits/stdc++.h>//#defineintlonglong#definell__int128#definedbdouble#defineldblongdouble#definevovoid#defineendl'\n'#defin......
  • 题解:CF1988B Make Majority
    题目大意题面写得很清楚,我就不再赘述了。解题思路涉及知识点:字符串,构造。由于所有相邻的$0$合并完会变成一个$0$,所以先贪心地把所有挨在一起的$0$合并起来,放在一个新的字符串里。而且题目需要你判断是否最终是否能合并成一个$1$,所以$1$是不需要想$0$一样合并的,这......
  • 题解:CF1994B Fun Game
    涉及知识点:异或,字符串处理。解题思路‌异或是一种二进制运算,用于比较两个数字的差异。当两个输入不同时,异或运算的结果为1;当两个输入相同时,结果为0。现在就可以切掉本题了。设两个字符串分别为$a$,$b$。如果$a$和$b$完全相同,输出Yes。如果$a$中没有$1$且$b$......
  • 题解:CF633D Fibonacci-ish
    涉及知识点:枚举,STL。题目大意给你一个序列,让你选出一些元素,使其构成fibonacccccci数列,求数列的最大长度。解题思路定义一个桶,$mp_i$代表$i$这个数在输入序列当中出现的次数。由于$n\le1000$,所以可以直接暴力枚举fibonacccccci数列的前两个数。前两个数固定了,这......
  • vue 项目history模式刷新404问题解决办法
    前言vue项目history模式部署到服务器后,根路径访问没有问题,但是进入其他功能再刷新页面就会出现404,因为你没在nginx或者apache配置上面加上重定向跳转。解决办法,只需要加上这段配置:nginx配置内容:location/{try_files$uri$uri/@router;indexindex.html;}lo......
  • 蓝桥杯大赛 ——首场算法团队战题解
    1. 不同角度【算法赛】在生活中,我们总是根据数值的大小来判断两个数字的大小关系。例如,9999 总是小于 100100,999999 总是小于 10001000。但如果我们换一个角度,将 999999 和 10001000 看成是两个数字字符串,并用字典序来比较它们的大小,那么此时,999999 将大于 10001000。......