[杂题] HDU5288: OO’s Sequence

来源:互联网 发布:linux主目录是什么 编辑:程序博客网 时间:2024/05/18 07:32

显然是考虑一个数的贡献。我们相当于要对于每个数 ai,找到最大的 L 满足 Li, aL|ai,最小的 R 满足 aR|ai
注意到这个想借助调和级数搞的话,复杂度是不太对的,因为 a 中的数可以有重复,比如说一堆 1
n 不太大,其实暴力搞就好了,直接扫两趟,对于每个 ai 直接枚因子…
复杂度 O(nV)

#include<cstdio>#include<vector>#include<cstring>#include<algorithm>using namespace std;const int maxn=100005,maxv=10005,MOD=1e9+7;typedef long long LL;int n,a[maxn],pos[maxv],L[maxn],R[maxn];LL ans;vector<int> dv[maxv];int main(){    freopen("hdu5288.in","r",stdin);    freopen("hdu5288.out","w",stdout);    for(int i=1;i<=10000;i++)     for(int j=i;j<=10000;j+=i) dv[j].push_back(i);    while(scanf("%d",&n)==1){        for(int i=1;i<=n;i++) scanf("%d",&a[i]);        memset(pos,0,sizeof(pos));        memset(L,0,sizeof(L));        for(int i=1;i<=n;i++){            for(int j=0;j<dv[a[i]].size();j++) L[i]=max(L[i],pos[dv[a[i]][j]]);            pos[a[i]]=i;        }        for(int i=1;i<=10000;i++) pos[i]=n+1;         memset(R,63,sizeof(R));        for(int i=n;i>=1;i--){            for(int j=0;j<dv[a[i]].size();j++) R[i]=min(R[i],pos[dv[a[i]][j]]);            pos[a[i]]=i;        }        ans=0;        for(int i=1;i<=n;i++) (ans+=(LL)(i-L[i])*(R[i]-i)%MOD)%=MOD;        printf("%lld\n",ans);    }    return 0;} 
原创粉丝点击