首页 > 其他分享 >CF1873F Money Trees

CF1873F Money Trees

时间:2023-10-15 17:15:50浏览次数:38  
标签:int Money Trees que res CF1873F

CF1873F Money Trees

双指针好题,但是我用的队列(


考虑先找出所有极长的、满足任意一个数都能被它后面的那个数整除的连续段。显然这个操作可以在 \(\mathcal{O}(n)\) 的时间复杂度内完成。

求出每个极长连续段的答案,取 \(\max\) 即为最终答案。那么现在的问题就是求一个数列中,满足和不超过正整数 \(m\) 的子串的最长长度。

注意到这个问题可以使用双指针法解决:右端点从左向右扫,每 \(+1\) 就相当于加入一个值。同时维护当前选中的数的和,如果超过 \(m\) 就删除之前的数,直到和 \(\le m\)。在维护过程中更新答案即可。

时间复杂度 \(\mathcal{O}(n)\)。代码使用了 std::queue,和双指针本质相同。

#include<bits/stdc++.h>
using namespace std;
#define int long long
bool Mbegin;
void File_Work(){
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
}
namespace Fast_In_Out{
	char buf[1<<21],*P1=buf,*P2=buf;
	#define gc (P1==P2&&(P2=(P1=buf)+fread(buf,1,1<<21,stdin),P1==P2)?EOF:*P1++)
	int read(){
		int f=1,x=0;
		char c=gc;
		while(c<'0'||c>'9'){
			if(c=='-')
			    f=-1;
			c=gc;
		}
		while(c>='0'&&c<='9'){
			x=x*10+c-'0';
			c=gc;
		}
		return f*x;
	}
	void write(int x){
		if(x<0)
			x=-x,putchar('-');
		if(x>9)
			write(x/10);
		putchar(x%10+'0');
	}
	#undef gc
}
using namespace Fast_In_Out;
typedef pair<int,int> pii;
const int N=2e5+8,oo=1e18+8;
int n,m,a[N],b[N];
vector<pii> vec;
int work(int ll,int rr){
	queue<int> que;
	int now=0,res=0,siz=0;
	for(int i=ll;i<=rr;i++){
		if(now<=m){
			now+=a[i];
			que.push(a[i]);
			siz++;
		}
		while(now>m&&que.empty()==0){
			now-=que.front();
			que.pop();
			siz--;
		}
		res=max(res,siz);
	}
	return res;
}
void solve(){
	vec.clear();
	for(int i=1;i<=n;i++)
		a[i]=b[i]=0;
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	for(int i=1;i<=n;i++)
		b[i]=read();
	b[0]=b[n+1]=oo;
	int pos=1;
	for(int i=1;i<=n;i++){
		if(b[i]%b[i+1]!=0){
			vec.push_back({pos,i});
			pos=i+1; 
		}
	}
	int ans=0;
	for(auto cur:vec){
		int l=cur.first,r=cur.second;
		int tmp=work(l,r);
//		write(tmp),putchar(' ');
		ans=max(ans,tmp);
	}
	write(ans),putchar('\n');
}
bool Mend;
signed main(){
//	File_Work();
	fprintf(stderr,"%.3lf MB\n\n\n",(&Mbegin-&Mend)/1048576.0);
	int testnum=read();
	while(testnum--)
		solve();
	fprintf(stderr,"\n\n\n%.0lf ms",1e3*clock()/CLOCKS_PER_SEC);
	return 0;
}

标签:int,Money,Trees,que,res,CF1873F
From: https://www.cnblogs.com/NatoriBlog/p/17765807.html

相关文章

  • JavaSE---SortedSet(TreeSet)
    SortedSet概述A{@linkSet}thatfurtherprovidesatotalorderingonitselements.提供元素排序的set;Theelementsareorderedusingtheir{@linkplainComparablenatural ordering},orbya{@linkComparator}typicallyprovidedatsortedsetcre......
  • 题解 CF457F 【An easy problem about trees】
    尝试理解,感谢cz_xuyixuan的题解。算作是很多情况的补充说明。我们不妨先二分答案,将\(\gemid\)的设为\(1\),\(<mid\)的设为\(0\),于是问题转化为了权值均为\(0/1\)的版本。我们称一棵树的大小为其非叶节点数。我们称一棵大小为奇数的树为奇树,大小为偶数的树为偶树。对......
  • 【bitset】【线段树】CF633G Yash And Trees 题解
    CF633G简单题。先看到子树加和子树质数个数和,果断转换为dfs序进行处理。既然有区间求和,考虑线段树。若对于每一个节点维护一个\(cnt\)数组,用二进制数\(x\)来表示,即当\(cnt_i=1\)时第\(i\)位为\(1\)。设当前节点为\(u\),左右子节点分别为\(ls\)和\(rs\)。发现......
  • CF1873F Money Trees
    思路要求最长长度,想到可以二分答案。那么现在需要考虑如何快速验证答案是否正确。可以\(O(n)\)枚举区间左端点,因为有了长度,所以可以直接获得右端点的值,直接验证右端点是否合法。因为要求区间的每个数都是右边的数的倍数,所以可以提前预处理每个点最远的满足这个条件的右端点,......
  • 你知道Vue 3.0中Treeshaking特性吗?
    介绍Vue3.0引入了Tree-shaking特性,旨在优化构建过程并减小最终生成的代码大小。Tree-shaking是一种在构建时移除未使用代码的技术,通过分析模块的依赖关系,将没有被引用的部分从最终的打包文件中排除掉。这可以大大减少应用的体积,提高性能。举个通俗一点的例子:当我们开发一个应用程......
  • 【Java 基础篇】Java TreeSet 详解:红黑树实现的有序集合
    Java集合框架提供了多种数据结构,用于存储和操作数据。其中,TreeSet是一种特殊类型的集合,它通过红黑树(Red-BlackTree)数据结构实现了有序的、唯一元素存储。本篇博客将深入探讨TreeSet,包括其概念、特性、内部实现、使用方法以及示例代码。无论您是初学者还是有一定经验的Java开......
  • CF1873F
    二分+前缀和。要求使得区间和小于\(k\)的子区间长度,显然可以二分处理。二分区间长度,枚举区间左端点,check两项内容:区间是否合法(符合\(h_i\modh_{i+1}=0\)),区间和是否小于\(k\)。对于当前区间长度,只要有一个区间满足条件,即返回真。区间和可以通过前缀和\(O(1)\)的计算,而......
  • money详细日志分析--转
    一、Monkey日志详解Monkey日志由以下几部分组成:(1)测试命令信息:随机种子seed、运行次数、可运行应用列表、各事件百分比。​​​​​​​ (2)App切换和Activity跳转:可以看到切换到了哪个App,从哪个Activity跳转到了哪个Activity,如果发生了异常,就可以看出是在哪个A......
  • 【题解】CF1830A Copil Copac Draws Trees
    你考虑对于每一条边打上时间标记,然后在树上DFS的时候维护一下以\(u\)为根的答案即可,然后将答案合并,反正很简单,看代码就懂。code:#include<bits/stdc++.h>usingnamespacestd;constintNN=2e5+8;intt,n;structEdge{ intto,next,val;}edge[NN<<1];inthead[......
  • 2023.9.3 hpz's problems about trees
    P2664树上游戏对于颜色\(c\),如果我们把颜色\(c\)的点全部都删除,那么我们会得到若干个连通块。连通块里面的路径是没有贡献的,连通块联通外面的路径都会有这个颜色做了贡献。对于一个连通块,其里面所有点都能有\(n-siz(连通块)\)的贡献。如果我们每次枚举颜色,再计算连通块,......