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)
Output
For each tests: ouput a line contain a number ans.
Sample Input
5 1 2 3 4 5
Sample Output
23
题意:
求每一个[L, R]区间中 j!=i a[i]对任意a[j]取余为0 的i的个数的总和
方法:
对于ai,看ai左边最近的位置l,al是ai的因数,右边位置r,ar是ai的因数。那么满足的个数就是(i-l)*(r-i)
预处理所有1-10000的因数。
从左到右,用pre[i]表示数字i出现的i的最右边的位置。算出每个位置的l。
同理从右到左,算出每个位置的r。
代码题解:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 100007
vector<int> head[10007];
int pre[10007];
int num[maxn];
int lef[maxn];
int righ[maxn];
int main()
{
int n;
for(int i = 1; i < 10000; i++)
{
head[i].clear();
for(int j = 1; j * j <= i; j++)
{
if(i % j == 0)
{
head[i].push_back(j);
head[i].push_back(i / j); head[i]存储i的所有因子
}
}
}
while(scanf("%d", &n) != EOF)
{
for(int i = 1; i <= n; i++)
scanf("%d", &num[i]);
memset(pre, 0, sizeof(pre));
for(int i = 1; i <= n; i++)
{
int u = num[i];
int p = 0;
for(int j = 0; j < head[u].size(); j++)
p = max(p, pre[head[u][j]]);
lef[i] = p;
pre[u] = i;
}
memset(pre, 0x3f, sizeof(pre));
for(int i = n; i > 0; i--)
{
int u = num[i];
int p = n + 1;
for(int j = 0; j < head[u].size(); j++)
p = min(p, pre[head[u][j]]);
righ[i] = p;
pre[u] = i;
}
long long ans = 0, l, r;
long long mod = 1000000007;
for(int i = 1; i <= n; i++)
{
ans += (long long)(i - lef[i]) * (righ[i] - i);
ans %= mod;
}
cout << ans << endl;
}
return 0;
}