• [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.

     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
    ",dfs(1,n));
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    Redis持久化
    《Hadoop权威指南·大数据的存储与分析》阅读笔记(未读完)
    《redis设计与实现》第一版 阅读笔记(未看完)
    LSMTree -> SStable 初体验
    Goland实现Set操作
    使用Goland操作Redis详解
    使用Python操作Redis详解
    学习笔记
    docker技术入门与实战 第三版
    Shell(笔记)
  • 原文地址:https://www.cnblogs.com/3soon/p/11536234.html
Copyright © 2020-2023  润新知