hdu5288 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
在这里插入图片描述

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);
    }
}
发布了328 篇原创文章 · 获赞 1 · 访问量 9116

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/105168743
oo
今日推荐