OO’s Sequence
Problem Description
OO has got a array A of size n ,defined a function f(l,r) represent the number of i (l<=i<=r) , that there’s no j(l<=j<=r,j<>i) satisfy ai mod aj=0,now OO want to know
∑i=1n∑j=inf(i,j) mod (
109+7
).
Input
There are multiple test cases. Please process till EOF.
In each test case:
First line: an integer n(
n<=105
) indicating the size of array
Second line:contain n numbers ai(
0<ai≤10000
)
Output
For each tests: ouput a line contain a number ans.
Sample Input
5
1 2 3 4 5
Sample Output
23
思路:对于每个数,考虑他能出现在哪些区间里,假如左区间长度为l,右区间长度为r,那么它的数量就是l*r,所以求出每个数的左右区间即可,可以通过枚举他的因子的位置获得
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=100010;
const int INF=1000000010;
const int MOD=1e9+7;
int N,a[maxn];
int vis[maxn];
int L[maxn],R[maxn];
int main()
{
while(scanf("%d",&N)!=EOF)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=N;i++)
scanf("%d",&a[i]);
for(int i=1;i<=N;i++)
{
int k=sqrt(a[i]);
int tmp=-1;
for(int j=1;j<=k;j++)
{
if(a[i]%j)continue;
if(vis[j])tmp=max(tmp,vis[j]);
if(j*j!=a[i]&&vis[a[i]/j])tmp=max(tmp,vis[a[i]/j]);
}
if(tmp==-1)L[i]=i;
else L[i]=i-tmp;
vis[a[i]]=i;
}
memset(vis,0,sizeof(vis));
for(int i=N;i>=1;i--)
{
int k=sqrt(a[i]);
int tmp=INF;
for(int j=1;j<=k;j++)
{
if(a[i]%j)continue;
if(vis[j])tmp=min(tmp,vis[j]);
if(j*j!=a[i]&&vis[a[i]/j])tmp=min(tmp,vis[a[i]/j]);
}
if(tmp==INF)R[i]=N-i+1;
else R[i]=tmp-i;
vis[a[i]]=i;
}
LL ans=0;
for(int i=1;i<=N;i++)
(ans+=L[i]*R[i])%=MOD;
printf("%I64d\n",ans);
}
return 0;
}