OO’s Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 3569 Accepted Submission(s): 1301
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 a
i mod a
j=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<=10^5) indicating the size of array
Second line:contain n numbers a i(0<a i<=10000)
In each test case:
First line: an integer n(n<=10^5) indicating the size of array
Second line:contain n numbers a i(0<a i<=10000)
Output
For each tests: ouput a line contain a number ans.
Sample Input
5 1 2 3 4 5
Sample Output
23
Author
FZUACM
Source
Recommend
定义两个数组L[i],R[i],表示第i数左侧和右侧最接近它且值是a[i]因子的数字的位置,那么第i个数能贡献的答案就是(R[i]−i)∗(i−L[i]),因此每个数字x都去枚举它的因子y,然后左右找到一个值是y且最接近x的数,然后用他的位置更新一下L,R数组。时间复杂度O(n√a)。
/* ***********************************************
Author : ryc
Created Time : 2016-07-30 Saturday
File Name : E:\acmcode\hdoj\5288.cpp
LANGUAGE : c++
Copyright 2016 ryc All Rights Reserved
************************************************ */
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<vector>
#define MOD 1000000007
using namespace std;
const int maxn=1e5+10;
int num[maxn],vis[maxn];
int l[maxn],r[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
int cnt=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;++i){
scanf("%d",&num[i]);
cnt=max(cnt,num[i]);
l[i]=0;r[i]=n+1;
for(int j=num[i];j<=cnt;j+=num[i]){
if(vis[j]&&r[vis[j]]>i)r[vis[j]]=i;
}vis[num[i]]=i;
}cnt=0;
memset(vis,0,sizeof(vis));
for(int i=n;i>=1;--i){
cnt=max(num[i],cnt);
for(int j=num[i];j<=cnt;j+=num[i]){
if(vis[j]&&l[vis[j]]<i)l[vis[j]]=i;
}vis[num[i]]=i;
}
long long ans=0;
for(int i=1;i<=n;++i){
ans=(ans+(i-l[i])*(r[i]-i)%MOD)%MOD;
// printf("%lld\n",ans);
}
printf("%lld\n",ans);
}
return 0;
}