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

HDU 5288 OO’s Sequence(数学)——2015 Multi-University Training Contest 1

2016-08-22 18:08 387 查看
传送门

OO’s Sequence

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 3597 Accepted Submission(s): 1318


[align=left]Problem Description[/align] 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).

[align=left]Input[/align] 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)

[align=left]Output[/align] For each tests: ouput a line contain a number ans.
[align=left]Sample Input[/align]
5

1 2 3 4 5

[align=left]Sample Output[/align]
23


题目大意:

就是求给定的公式的值。

解题思路:

首先我们观察到 n 的数据范围 105 和 ai 的范围是 104 ,那么我们如果通过正常的方

法来做的话是O(n2) 的,顶多剪剪枝,那也肯定的是超时的,所以我们看到了 ai 的范

围,所以我们可以先对每一个 1−104 区间的数找到每个数的因子,先进行预处理一

遍,然后进行分析,对于每个数 ai 找到 左边离 ai 最近的因子 al(如果没有 l 就是 0)

然后找到右边离 ai 最近的因子 ar ,然后这个 ai 对答案的贡献就是

(i−l) ∗ (r−i), 求左右离 ai 最近的因子就是一个从前往后扫一遍,一个从后往前扫

一遍就行了。

My Code:

/**
2016 - 08 - 22 下午
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9+5;
const int MAXN = 1e4+5;
const int MOD = 1e9+7;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
LL Scan_LL()///输入外挂
{
LL res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
int Scan_Int()///输入外挂
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
void Out(LL a)///输出外挂
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
vector <int> vec[MAXN];
void Init()
{
for(int i=1; i<MAXN; i++)
{
for(int j=1; j*j<=i; j++)
{
if(i%j == 0)
{
vec[i].push_back(j);
if(i/j != j)
vec[i].push_back(i/j);
}
}
}
}
int a[MAXN*10], pre[MAXN*10], left1[MAXN*10], right1[MAXN*10];
int main()
{
Init();
int n;
while(~scanf("%d",&n))
{
for(int i=1; i<=n; i++)
a[i] = Scan_Int();
memset(pre, 0, sizeof(pre));
for(int i=1; i<=n; i++)
{
int p = 0;
for(int j=0; j <vec[a[i]].size(); j++)
p = max(p, pre[vec[a[i]][j]]);
left1[i] = p;
pre[a[i]] = i;
}
for(int i=0; i<MAXN; i++)
pre[i] = INF;
for(int i=n; i>0; i--)
{
int p = n+1;
for(int j=0; j <vec[a[i]].size(); j++)
p = min(p, pre[vec[a[i]][j]]);
right1[i] = p;
pre[a[i]] = i;
}
int ans = 0;
for(int i=1; i<=n; i++)
ans = (ans + (i-left1[i])*(right1[i]-i) ) % MOD;
ans = (ans%MOD+MOD) % MOD;
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: