zoukankan      html  css  js  c++  java
  • 【STSRM12】整除

    【题意】给定长度为n的序列A,求最长的区间满足区间内存在数字能整除区间所有数字,同时求所有方案。n<=5*10^5,Ai<2^31。

    【算法】数论???

    【题解】首先一个区间的基准数一定是最小的数字。

    以一个数字为基准数,左右扩展到的区间内的数字都不能再作为基准数(不会超过此时的区间,为同一个)。

    从小到大选取基准数并左右扩展(标记),标记过的不再作为基准数。

    复杂度O(n log n)。(排序的复杂度)

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=500010;
    int a[maxn],p[maxn],n,ans,ansx,b[maxn];
    bool vis[maxn];
    bool cmp(int x,int y){return a[x]<a[y];}
    void work(int x){
        if(vis[x])return;
        int l,r;
        for(l=x;l>=1&&a[l]%a[x]==0;l--)vis[l]=1;
        for(r=x;r<=n&&a[r]%a[x]==0;r++)vis[r]=1;
    //    printf("l=%d r=%d
    ",l,r);
        if(r-l-2>ans){ans=r-l-2;p[ansx=1]=l+1;}
        else if(r-l-2==ans){p[++ansx]=l+1;}
    }    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){scanf("%d",&a[i]);b[i]=i;}
        sort(b+1,b+n+1,cmp);
        for(int i=1;i<=n;i++)work(b[i]);
        sort(p+1,p+ansx+1);
        printf("%d %d
    ",ansx,ans);
        for(int i=1;i<=ansx;i++)printf("%d ",p[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    iOS学习-UILabel
    react js
    代理模式
    利用gitbush从git上下载代码到本地
    VS2017企业版密钥
    office2016产品密钥及激活工具
    .netframe初识
    树的遍历——c#实现
    数据结构——总结
    单例模式
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7340048.html
Copyright © 2011-2022 走看看