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

【遍历枚举】hdu 5288 OO’s Sequence

2015-09-20 20:43 543 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5288

题意:给出一个序列,计算所有满足:存在ai使的区间内不存在ai的倍数的区间个数和

分析:从ai先两端找到不是ai倍数的两个端点了,li,ri。sum(i)=(loc(ai)-li)*(ri-loc(ai));

#include<stdio.h>

#include<string.h>

#include<iostream>

#include<algorithm>

#include<vector>

using namespace std;

const int maxn=100000+10;

const int maxh=10000+10;

const int mode=1000000007;

int num[maxn],r[maxn],l[maxn];

int rr[maxh],ll[maxh];

vector<int>vec[maxh];

void init()

{

for(int i=1;i<=10000;i++)//计算出10000以内每个输的倍数

for(int j=1;j*j<=i;j++)

{

if(!(i%j))

{

vec[j].push_back(i);

if(j*j!=i)

vec[i/j].push_back(i);

}

}

}

int main()

{

int n;

long long int sum;

init();

while(scanf("%d",&n)!=EOF)

{

for(int i=0;i<=10000;i++)

{

ll[i]=0;

rr[i]=n+1;

}

for(int i=1;i<=n;i++)

scanf("%d",&num[i]);

for(int i=1;i<=n;i++)//找到每个数的做端点

{

l[i]=ll[num[i]];

int h=vec[num[i]].size();

for(int j=0;j<h;j++)

ll[vec[num[i]][j]]=i;

}

for(int i=n;i>=1;i--)//找到每个数的又端点

{

r[i]=rr[num[i]];

int h=vec[num[i]].size();

for(int j=0;j<h;j++)

rr[vec[num[i]][j]]=i;

}

sum=0;

for(int i=1;i<=n;i++)

{

sum+=(i-l[i])*(r[i]-i);

if(sum>=mode)

sum%=mode;

}

printf("%I64d\n",sum);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: