首页 > 其他分享 >LeetCode2447 最大公因数等于 K 的子数组数目 题解

LeetCode2447 最大公因数等于 K 的子数组数目 题解

时间:2022-10-25 09:24:41浏览次数:86  
标签:gcd log nums int 题解 复杂度 端点 LeetCode2447 公因数

看到这题,发现可以直接枚举字串进行 check,复杂度是 \(\mathcal O(n^2(n+\log w))\),但是可以固定左端点,向右推右端点统计答案优化到 \(\mathcal O(n(n+\log w))\)。
虽然这里 \(n\le1000\) 能够通过但是我觉得复杂度不够优秀,考虑 \(\gcd\) 每次除以 \(2\) 的性质,发现固定左端点后右端点只有 \(\log\) 次变化,那么就可以二分(或倍增)出 \(\gcd=k\) 的那一段然后去统计答案。
对于维护区间 \(\gcd\) 可以使用线段树或者 ST 表去维护,总复杂度是 \(\mathcal O(n\log w\log n)\)。
代码:

#include<bits/stdc++.h>
using namespace std;
#define siz(x) int((x).size())
#define all(x) (x).begin(),(x).end()
class Solution {
	static constexpr int N=1001,M=__lg(N)+1;
	int st[M][N];
	int query(int l,int r){
		int t=__lg(r-l+1);
		return gcd(st[t][l],st[t][r-(1<<t)+1]);
	}
public:
	int subarrayGCD(vector<int>& nums, int k) {
		int n=siz(nums),ans=0;
		nums.insert(nums.begin(),0);
		for(int i=1;i<=n;i++)st[0][i]=nums[i];
		for(int j=1;(1<<j)<=n;j++)for(int i=1;i+(1<<j)-1<=n;i++)
			st[j][i]=gcd(st[j-1][i],st[j-1][i+(1<<(j-1))]);
		for(int i=1;i<=n;i++){
			if(nums[i]<k)continue;
			int l=i;
			for(int j=__lg(n);~j;j--)
				if(l+(1<<j)<=n&&query(i,l+(1<<j))>k)l+=(1<<j);
			int r=max(i,l);
			for(int j=__lg(n);~j;j--)
				if(r+(1<<j)<=n&&query(i,r+(1<<j))>=k)r+=(1<<j);
			ans+=r-l;
			if(l==i&&nums[i]==k)ans++;
		}
		return ans;
	}
};
// int main(){
// 	int n,k;
// 	std::vector<int>nums;
// 	cin>>n>>k;	
// 	nums.resize(n);
// 	for(int&i:nums)cin>>i;
// 	cout<<Solution{}.subarrayGCD(nums,k);
// }

标签:gcd,log,nums,int,题解,复杂度,端点,LeetCode2447,公因数
From: https://www.cnblogs.com/bxjz/p/16823788.html

相关文章

  • P6533 RELATIVNOST 题解
    P6533RELATIVNOST题解目录P6533RELATIVNOST题解题目分析思路代码题目洛谷P6533RELATIVNOST分析题目中要求至少有\(c\)人买走至少一张彩色画,那暴力的思路就是......
  • 【题解】ABC259Ex Yet Another Path Counting
    Sol考虑两种暴力。直接枚举同类点,组合数计算两点之间的路径数。单次操作时间复杂度\(O(B^2)\)。其中\(B\)表示这类点的个数。暴力dp,记\(dp_{i,j}\)表示到\((i,j......
  • Codeforces Round #829-1754A+B与1753A+B+C 题解
    1754A-TechnicalSupport题意给定一个只包含大写字母\(\texttt{Q}\)和\(\texttt{A}\)的字符串,如果字符串里的每一个\(\texttt{Q}\)都能与在其之后的\(\texttt{A......
  • 【题解】ABC259F Select Edges
    Sol考虑dp。记\(dp_{u,0/1}\)表示\(u\)点是否向上连边的最大值。转移的话相当于是找若干个\(dp_{v,1}+w(u,v)\)进行转移。其中\(w(u,v)\)表示\((u,v)\)这条......
  • 2022级HAUT新生周赛题解汇总
    2022级HAUT新生周赛(零)题解@:2022级HAUT新生周赛(一)题解@卞子骏:2022级HAUT新生周赛(二)题解@武其轩:2022级HAUT新生周赛(三)题解@焦小航:2022级HAUT新生周赛(四)题解@张子豪:202......
  • leetcode刷题MySQL题解十八
    leetcode刷题MySQL题解十八题目叙述Views表:±--------------±--------+|ColumnName|Type|±--------------±--------+|article_id|int||author_id|int|......
  • leetcode刷题MySQL题解十五
    leetcode刷题MySQL题解十五题目叙述Employee表:±------------±-----+|ColumnName|Type|±------------±-----+|id|int||salary|int|±------------±......
  • leetcode刷题MySQL题解十三
    leetcode刷题MySQL题解十三题目叙述表:Products±------------±--------+|ColumnName|Type|±------------±--------+|product_id|int||store1|int||st......
  • leetcode刷题MySQL题解十四
    leetcode刷题MySQL题解十四题目叙述给定一个表tree,id是树节点的编号,p_id是它父节点的id。±—±-----+|id|p_id|±—±-----+|1|null||2|1||3|1......
  • leetcode刷题MySQL题解十二
    leetcode刷题MySQL题解十二题目叙述表:Employees±------------±--------+|ColumnName|Type|±------------±--------+|employee_id|int||name|varchar......