您的位置:首页 > 产品设计 > UI/UE

hdu 5288 OO’s Sequence

2015-07-22 01:18 501 查看


OO’s Sequence

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 758 Accepted Submission(s): 281



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

∑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 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




给出n个数 枚举所有的子区间的情况 在这些区间中 有多少个数 这个数与该区间中其他所有的数互素

对于每一个数a[i] 找出区间的边界l[i] r[i] 在这个区间中所有的数都是与a[i]互素的

包含a[i]且使得a[i]满足条件的个数为(i-l[i]+1)*(r[i] - i + 1)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>

#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MAXN 100010
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)

using namespace std;

int Read()
{
    char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    int x = 0;
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

void Print(int a)
{
     if(a>9)
         Print(a/10);
     putchar(a%10+'0');
}

ll l[MAXN],r[MAXN];
ll pre[MAXN],last[MAXN];
int a[MAXN];
const ll MOD=1e9+7;

int main()
{
    //fread;
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            l[i]=1; r[i]=n;
        }
        MEM(pre,0); MEM(last,0);
        for(int i=1;i<=n;i++)
        {
            for(int j=a[i];j<=10000;j+=a[i])
            {
                if(pre[j]!=0&&r[pre[j]]==n)//已经出现且没有找到右边的边界
                    r[pre[j]]=i-1;
            }
            pre[a[i]]=i;
        }
        for(int i=n;i>0;i--)
        {
            for(int j=a[i];j<=10000;j+=a[i])
            {
                if(last[j]!=0&&l[last[j]]==1)
                    l[last[j]]=i+1;
            }
            last[a[i]]=i;
        }
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            ans=(ll)(ans%MOD+(ll)((i-l[i]+1)*(r[i]-i+1)%MOD)%MOD);
            ans%=MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: