[LUOGU]P5502 [JSOI2015]最大公约数
题意:给一个序列a[1],a[2],a[3]...a[n],求其中连续的子序列A[L],A[L+1],...,A[R],使其权值 W(L,R)=(R-L+1)×gcd(A[L],...,A[R])最大。
思路:
简单的一个分治思想。
先想想线段树里询问怎么做的?
是不是把这个区间从中间砍开。然后丢到左/右儿子那里再问。
同样的,在这里,对于所要求的ans区间
也是可以 劈开 讨论的
·ans区间全在当前区间(l,r) 的右侧(l,mid);
·ans区间全在当前区间(l,r) 的左侧(mid+1,r);
·ans区间横跨左右儿子;
对前俩种,直接往下递归就行。
第三种,枚举一遍整个(l,r)区间,找到含有a[mid]的最大权值区间就行。此处复杂度约O(n).
p.s.第三种情况可以从mid开始向两边拓展。
OVER.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define re register 4 #define LL long long 5 #define DB double 6 #define For(x,a,b) for(re int x=a;x<=b;x++) 7 #define For2(x,a,b) for(re int x=a;x>=b;x--) 8 #define LFor(x,a,b) for(re LL x=a;x<=b;x++) 9 #define LFor2(x,a,b) for(re LL x=a;x>=b;x--) 10 #define Abs(x) ((x>0)? x:-x) 11 int gi() 12 { 13 int res=0,fh=1;char ch=getchar(); 14 while((ch>'9'||ch<'0')&&ch!='-') ch=getchar(); 15 if(ch=='-') fh=-1,ch=getchar(); 16 while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar(); 17 return fh*res; 18 } 19 LL gl() 20 { 21 LL res=0,fh=1;char ch=getchar(); 22 while((ch>'9'||ch<'0')&&ch!='-') ch=getchar(); 23 if(ch=='-') fh=-1,ch=getchar(); 24 while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar(); 25 return fh*res; 26 } 27 int n; 28 LL a[100005],ans; 29 LL gcd(LL x,LL y) {return y==0? x:gcd(y,x%y);} 30 LL deal(int l,int r,int L,int R) 31 { 32 LL _gcd=a[l],val=a[l],f=l; 33 while(L<l&&r<R) 34 { 35 _gcd=gcd(_gcd,a[l-1]); 36 l--; 37 while(r<=R&&a[r]%_gcd==0) r++; 38 while(L<=l&&a[l]%_gcd==0) l--; 39 val=val<(LL)(r-l-1)*_gcd? (LL)(r-l-1)*_gcd:val; 40 l++,r--; 41 } 42 l=r=f; 43 _gcd=a[r]; 44 while(L<l&&r<R) 45 { 46 _gcd=gcd(_gcd,a[r+1]); 47 r++; 48 while(L<=l&&a[l]%_gcd==0) l--; 49 while(r<=R&&a[r]%_gcd==0) r++; 50 val=val<(LL)(r-l-1)*_gcd? (LL)(r-l-1)*_gcd:val; 51 l++,r--; 52 } 53 return val; 54 } 55 LL dfs(int l,int r) 56 { 57 if(l==r) return a[l]; 58 int mid=l+r>>1; 59 LL opt1=deal(mid,mid,l,r); 60 LL opt2=dfs(l,mid); 61 LL opt3=dfs(mid+1,r); 62 return max(opt1,max(opt2,opt3)); 63 } 64 65 int main() 66 { 67 n=gi(); 68 For(i,1,n) a[i]=gl(); 69 printf("%lld\n",dfs(1,n)); 70 return 0; 71 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步