CF359D:Pair of Numbers——题解

https://vjudge.net/problem/CodeForces-359D

http://codeforces.com/problemset/problem/359/D

题目大意:

给一串数,问一个区间内所有的数是否能被其其中一个数所全部整除,求出满足条件的区间的长度最大值,并输出这样的区间的个数与它们的左端点。

换句话将,求区间GCD=区间MIN的最大长度区间。

明显st表解决。

对于最大区间长度,二分判断即可。

(因为在poj做过类似的题所以思路能很快……就是题看不懂有点难,所以特地给出翻译)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1e5*3+1;
inline int read(){
    int X=0,w=0; char ch=0;
    while(ch<'0' || ch>'9') {w|=ch=='-';ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
inline int qpow(int a){
    if(a==0)return 1;
    return (1<<a);
}
int gcdd[N][30];
int minn[N][30];
int log[N];
int n;
int gcd(int a,int b){
    if(!b)return a;
    return gcd(b,a%b);
}
void st(){
    for(int j=1;j<=log[n];j++){
    for(int i=1;i<=n;i++){
        int p=i+qpow(j)-1;
        if(p>n)continue;
        gcdd[i][j]=gcd(gcdd[i][j-1],gcdd[i+qpow(j-1)][j-1]);
        minn[i][j]=min(minn[i][j-1],minn[i+qpow(j-1)][j-1]);
    }
    }
    return;
}
bool pan(int k){
    for(int i=1;i<=n;i++){
    int j=i+k;
    if(j>n)break;
    int l=log[k];
    int p=qpow(l);
    int GCD=gcd(gcdd[i][l],gcdd[j-p+1][l]);
    int MIN=min(minn[i][l],minn[j-p+1][l]);
    if(GCD==MIN)return 1;
    }
    return 0;
}
int len;
void erfen(int l,int r){
    if(l>r)return;
    int mid=(l+r)>>1;
    if(pan(mid)){
    len=mid;
    erfen(mid+1,r);
    }else{
    erfen(l,mid-1);
    }
    return;
}
vector<int>ans;
int main(){
    n=read();
    log[0]=-1;
    for(int i=1;i<=n;i++){
    gcdd[i][0]=minn[i][0]=read();
    log[i]=log[i>>1]+1;
    }
    log[0]=0;
    st();
    erfen(0,n-1);
    for(int i=1;i<=n;i++){
    int j=i+len;
    if(j>n)break;
    int l=log[len];
    int p=qpow(l);
    int GCD=gcd(gcdd[i][l],gcdd[j-p+1][l]);
    int MIN=min(minn[i][l],minn[j-p+1][l]);
    if(GCD==MIN)ans.push_back(i);
    }
    printf("%d %d
",(int)ans.size(),len);
    for(int i=0;i<ans.size();i++){
    printf("%d ",ans[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/luyouqi233/p/7884038.html