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
  • 相关阅读:
    进程空间与系统空间(一)
    内核之最
    Linux 内核3.10.5 专场
    device_create与device_register
    重写与重载的含义
    抽象类和接口的区别
    Spring知识点
    mybatis学习
    知识点
    Mybatis面试题
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7340048.html
Copyright © 2011-2022 走看看