• CC Subarray LCM (数学)


    题目连接:http://www.codechef.com/problems/SUBLCM

    题意:给定一个序列,求最长连续子序列满足 LCM(Ai,Ai+1...Aj) =Ai*Ai+1*...*Aj。

    分析:若要满足 LCM(Ai,Ai+1...Aj) =Ai*Ai+1*...*Aj,必须子序列内两两互质(没有相同质因子),因此首先筛素因子。

    由dp[i]表示从a[i]开始往回走,最远到达pos还满足 LCM(Apos,Ai+1...Ai) =Apos*Apos+1*...*Ai  ,则dp[i]取决于dp[i-1]和之前有没有最右出现a[i]含有的质因子。

    用一个数组记录每个质因子最右出现的位置,则dp[i]=max(dp[i-1],last)(last表示a[i]含有的质因子出现最右的位置)

    最后ans=max(ans,i-dp[i]+1)即可。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 100000000
    #define inf 0x3f3f3f3f
    #define N 1000010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    vector<int>PrimeFactor[N];
    int prime[N];
    int gcd(int a,int b)
    {
        return a%b==0?b:gcd(b,a%b);
    }
    void init()
    {
        for(int i=2;i<N;i++)//筛素因子
        {
            if(!prime[i])
            {
                for(int j=i;j<N;j+=i)
                    PrimeFactor[j].push_back(i),prime[j]=1;
            }
        }
    }
    int pos[N],dp[N],a[N];
    int main()
    {
        init();
        int T,n,x;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            FILL(pos,0);
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                x=a[i];
                int maxlast=0;
                for(int j=0,sz=PrimeFactor[x].size();j<sz;j++)//找出a[i]含有的质因子最右位置
                {
                    int factor=PrimeFactor[x][j];
                    maxlast=max(maxlast,pos[factor]+1);
                    pos[factor]=i;
                }
                if(i>1&&gcd(a[i],a[i-1])!=1)
                {
                    dp[i]=i;continue;
                }
                dp[i]=max(maxlast,dp[i-1]);
            }
            for(int i=1;i<=n;i++)ans=max(ans,i-dp[i]+1);
            if(ans<=1)ans=-1;
            printf("%d
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    重构之重新组织函数(ExTract Method)
    设计模式之桥接模式
    设计模式原则之里氏替换原则
    设计模式原则之依赖倒置原则
    设计模式原则之接口隔离原则
    设计模式原则之单一职责原则
    编译php5.6
    wireshark总结
    Blu-Ray BRRip 和 BDRip 的区别
    openwrt虚拟机的network unreachable
  • 原文地址:https://www.cnblogs.com/lienus/p/4251758.html
Copyright © 2020-2023  润新知