ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】CF1438E Yurii Can Do Everything

2022-07-06 13:31:57  阅读:106  来源: 互联网

标签:Do log int 题解 highbit 枚举 端点 复杂度 Yurii


我的垃圾做法好像和别人有些不同,分享一下。

题目传送门:luoguCF

规定:记序列 \(s\) 表示序列 \(a\) 的前缀和,\(highbit(x)\) 表示数 \(x\) 的最高位,序列 \(a\) 值域为 \(m\)。

首先考虑枚举一个端点找答案,不妨枚举 \(l\),然后寻找枚举 \(r\) 的性质来减少枚举。

考虑左端点 \(l\),不难发现对于一个 \(l\) 之后最小的位置 \(k\) 满足 \(highbit(s_k-s_l)>highbit(a_l)\),\(k\) 之后的所有位置 \(j\) 若要作为右端点 \(r\),因为 \(a_l\) 的第 \(highbit(s_{j-1}-s_l)\) 位必然为 \(0\),所以 \(j\) 必须满足 \(highbit(a_j) \geq highbit(s_{j-1}-s_l)\),这时,对于 \(j\) 后的每一个位置 \(j'\),显然 \(highbit(s_{j'-1}-s_l)\) 大于 \(highbit(s_{j-1}-s_l)\),而 \(highbit\) 至多增大到 \(\log_2 m\),所以 \(k\) 后满足条件的右端点数量最多只有 \(\log m\) 个。根据这个结论,只要对于每个位置预处理它后面第一个 \(highbit(a_j)\) 大于某个位的位置 \(j\),即可将对满足 \(r>k\) 的右端点 \(r\) 的枚举优化到 \(O(n\log_2 m)\) 的复杂度。

然后考虑 \(r\leq k\) 的情况,直接暴力做复杂度就是对的,别的题解里都有这部分的证明,我就不再赘述。

时空复杂度均为 \(O(n\log_2 m)\),代码见下:

#include<bits/stdc++.h>
using namespace std;
#define re register
typedef double db;
typedef long long ll;
inline int win(){
	int x=0,w=0;char c=getchar();
	while(c>'9'||c<'0') w|=c=='-',c=getchar();
	while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return w?-x:x;
}

const int N=202020;
int p[N][31];ll a[N],s[N];

signed main(){
	int n=win(),ans=0;
	for(re int i=1;i<=n;++i) a[i]=win(),s[i]=a[i]+s[i-1];
	for(re int j=0;j<30;++j) p[n][j]=n+1;
	for(re int i=n,l;i>=1;--i){
		l=63-__builtin_clzll(a[i]);
		for(re int j=0;j<=l;++j) p[i-1][j]=i;
		for(re int j=l+1;j<30;++j) p[i-1][j]=p[i][j];
	}
	for(re int i=1,j,lmt;i<=n;++i){
		j=i+1,lmt=64-__builtin_clzll(a[i]);
		for(;j<n&&s[j]-s[i]<(1ll<<lmt);++j) if(s[j]-s[i]==(a[i]^a[j+1])) ++ans;
		if(j<n){
			lmt=63-__builtin_clzll(s[j]-s[i]),j=p[j][lmt];
			for(;j<=n&&lmt<=30;lmt=63-__builtin_clzll(s[j]-s[i]),j=p[j][lmt]) if((a[j]^a[i])==s[j-1]-s[i]) ++ans;
		}
	}
	printf("%d\n",ans);
	return 0;
}

标签:Do,log,int,题解,highbit,枚举,端点,复杂度,Yurii
来源: https://www.cnblogs.com/whale-at-cola/p/solution-cf1438e.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有