OO’s Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
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
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 100017
#define LL __int64
using namespace std;
const int mod = 1e9 + 7;
LL l[maxn], r[maxn];
LL a[maxn];
int main()
{
int n;
LL pre[maxn], last[maxn];
while (~scanf("%d", &n))
{
for (int i = 1; i <= n; i++)
{
scanf("%I64d", &a[i]);
l[i] = 1;
r[i] = n;
}
memset(pre, 0, sizeof(pre));
memset(last, 0, sizeof(last));
for (int i = 1; i <= n; i++) //右边界
{
for (int j = a[i]; j <= 10000; j += a[i]) //j是a[i]的倍数
{
if (pre[j] != 0 && r[pre[j]] == n) //j在左边曾经出现过 j的右边界尚未出现
{
r[pre[j]] = i - 1; //记录j右边界的位置 这个边界离j最近
}
}
pre[a[i]] = i; //左边曾经出现过的数与其位置
}
for (int i = n; i >= 1; i--) //左边界
{
for (int j = a[i]; j <= 10000; j += a[i])
{
if (last[j] != 0 && l[last[j]] == 1) //j在右边出现过 j的左边界尚未出现
{
l[last[j]] = i + 1;
}
}
last[a[i]] = i; //右边曾经出现的数的位置
}
LL ans = 0;
for (int i = 1; i <= n; i++)
{
ans += ((LL)(i - l[i] + 1) * (r[i] - i + 1)) % mod;
ans %= mod;
}
printf("%I64d\n", ans);
}
return 0;
}