题目链接
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
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 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
Author
FZUACM
Source
2015 Multi-University Training Contest 1
思路:我们考虑每个数的贡献,对于a【i】来说,能产生贡献的只有a【i】左边第一不mod为0的位置l,和只有a【i】右边第一不mod为0的位置r,贡献为(i-l)*(r-i)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+1;
const int mod=1e9+7;
vector<int>v[maxn],p[maxn];
int n,a[maxn];
void init()
{
for(int i=1;i<maxn;++i)
for(int j=1;i*j<maxn;++j)
v[i*j].push_back(i);
}
ll slove(int x,int y)
{
ll l=0,r=n+1;
for(int i=0;i<v[y].size();++i)
{
for(int j=0;j<p[v[y][i]].size();++j)
{
if(p[v[y][i]][j]<x) l=max(l,1LL*p[v[y][i]][j]);
if(p[v[y][i]][j]>x) r=min(r,1LL*p[v[y][i]][j]);
}
}
return (x-l)*(r-x);
}
int main()
{
init();
while(scanf("%d",&n)!=EOF)
{
ll ans=0;
for(int i=1;i<maxn;++i) p[i].clear();
for(int i=1;i<=n;++i) scanf("%d",&a[i]),p[a[i]].push_back(i);
for(int i=1;i<=n;++i)
ans=(ans+slove(i,a[i]))%mod;
printf("%lld\n",ans);
}
}