zoukankan      html  css  js  c++  java
  • UVA 1642 Magical GCD(gcd的性质,递推)

    分析:对于区间[i,j],枚举j。

    固定j以后,剩下的要比较M_gcd(k,j) = gcd(ak,...,aj)*(j-k+1)的大小, i≤k≤j。

    此时M_gcd(k,j)可以看成一个二元组(g, k)。

    根据gcd的性质gcd(a1,a2,...,an) = gcd(a1,gcd(a2,..,an)),而且gcd(a,b) | b。

    如果gcd(ak,...,aj) != gcd(ak+1,...,aj),那么gcd(ak,...,aj) ≤ 2*gcd(ak+1,...,aj)。

    原本有j个gcd,而不同的gcd值之间至少相差2倍,所以不同的gcd值的数量是O(log2j)。

    gcd相同的只要保留最小的k。

    把j-1对应的M_gcd的二元组保留成一个表tb。然后想想怎么递推j的表,

    根据gcd(a1,a2,...,aj) = gcd(gcd(a1,..aj-1),aj),一部分是tbj.g =  gcd(tbj-1.g,a[j]),下标没有改变,

    另一部分是二元组(a[j],j)。一个有序序列依次和a[j]求gcd以后不一定有序了,去重复前还要排下序。

    总的复杂度是O(nlogn*loglogn )

    /*********************************************************
    *      --------------Crispr---------------               *
    *   author AbyssalFish                                   *
    **********************************************************/
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    //list<ll> gcd_tab;
    //ll g_tb[64];
    //int idx[64];
    typedef pair<ll,int> pli;
    pli tb[64];
    
    int sz;
    
    ll gcd(ll a,ll b)
    {
        ll t;
        while(b){
            t = b;
            b = a%b;
            a = t;
        }
        return a;
    }
    
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        int T , n;
        scanf("%d",&T);
        ll a;
        while(T--){
            scanf("%d",&n);
            sz = 0;
            ll ans = 0;
    
            #define val first
            #define idx second
            for(int i = 0; i < n; i++){
                scanf("%lld",&a);
                for(int j = 0; j < sz; j++){
                    tb[j].val = gcd(tb[j].val,a);
                }
                tb[sz++] = pli(a,i-1);
                sort(tb,tb+sz);
                int k = 0;
                for(int j = 1; j < sz; j++){
                    if(tb[j].val != tb[k].val){
                        ans = max((i-tb[k].idx)*tb[k].val, ans);
                        if(++k != j) tb[k] = tb[j];
                    }
                }
                ans = max((i-tb[k].idx)*tb[k].val, ans);
                sz = k+1;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    html向servlet传乱码解决办法
    myeclipse破解方法
    django cookie
    django 时间计数
    bzoj1698 / P1606 [USACO07FEB]白银莲花池Lilypad Pond
    bzoj1689 / P1589 [Usaco2005 Open] Muddy roads 泥泞的路
    bzoj1660 / P2866 [USACO06NOV]糟糕的一天Bad Hair Day
    bzoj1657: [Usaco2006 Mar]Mooo 奶牛的歌声
    bzoj1655: [Usaco2006 Jan] Dollar Dayz 奶牛商店
    bzoj1654 / P2863 [USACO06JAN]牛的舞会The Cow Prom
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4964501.html
Copyright © 2011-2022 走看看