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

OO’s Sequence

2015-07-27 10:15 411 查看
                                    OO’s Sequence

题目抽象:给你一个整数序列。 对于它的每个非空的子集区间,有多少个整数不能整除其它数。求每个非空子集区间的这些数的总和。

分析:用L[i],R[i]表示a[i]中最近的约数。

超时代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <sstream>
using namespace std;
typedef long long LL;
const int INF = 0x4ffffff;
const double EXP = 1E-5;
const LL mod = 1e9+7;
const int MS= 1E5+5;
const int MS2 = 1e4+1;

int a[MS];
int L[MS];
int R[MS];

int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i = 1;i<=n;i++)
scanf("%d",&a[i]);
a[0] = 1;
a[n+1] = 1;

for(int i = 1;i<=n;i++)
{
for(int j = i-1;j>=0;j--)
{
if(a[i] % a[j] == 0)
{
L[i] = j;
break;
}
}

for(int j = i+1;j<=n+1;j++)
{
if(a[i] % a[j] == 0)
{
R[i] = j;
break;
}
}
}
LL ans=  0;
for(int i =1;i<=n;i++)
{
ans += (i - L[i]) * (R[i] - i);
ans %=mod;
}
printf("%lld\n",ans);
}
return 0;
}


优化: 由于每个整数不大于10000,我们可以预处理出每个数的约数。在处理L[i]和R[i]中,用pre数组来表示前面出现的整数。见代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <sstream>
using namespace std;
typedef long long LL;
const int INF = 0x4ffffff;
const double EXP = 1E-5;
const LL mod = 1e9+7;
const int MS= 1E5+5;
const int MS2 = 1e4+1;

int a[MS];
int L[MS];
int R[MS];
int pre[MS];
vector<int> vec[MS];

void init()
{
for(int i = 1;i<MS2;i++)
{
for(int j = i;j <MS2;j+=i)
{
vec[j].push_back(i);
}
}
}

int main()
{
init();
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i =1;i<=n;i++)
scanf("%d",&a[i]);
memset(pre,0,sizeof(pre));
for(int i = 1;i<=n;i++)
{
int t = 0;
for(int j =0;j<vec[a[i]].size();j++)
{
if(pre[vec[a[i]][j]])
t = max(t,pre[vec[a[i]][j]]);
}
L[i] = t;
pre[a[i]] = i;
}

memset(pre,0,sizeof(pre));
for(int i = n;i>0;i--)
{
int t = n+1;
for(int j = 0;j<vec[a[i]].size();j++)
{
if(pre[vec[a[i]][j]])
{
t = min(t,pre[vec[a[i]][j]]);
}
}
R[i] = t;
pre[a[i]] = i;
}
LL ans= 0;
for(int i = 1;i<=n;i++)
{
ans += (i - L[i]) * (R[i] - i);
ans %= mod;
}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: