标签:
给出n个数a1,a2...an,定义函数 f[i]=j,(i<j),表示aj mod ai=0 的最小j,其中j大于i,如果不存在这样的数,则f[i]=0
求n个数所有f[]值的和
先用筛法o(nlogn)求出每个数的约数
然后每读入一个数x,先找出所有的约数,再看看之前有没有出现过这些约数。
这个回看的过程可以用一个数组维护。
维护watch[],watch[aj]=j 表示aj还没有找到函数值,如果aj是x的约数,那么说明aj的函数值为x的位置。
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> #include<map> #include<stack> #include<vector> #include<queue> #include<string> #include<sstream> #define eps 1e-9 #define ALL(x) x.begin(),x.end() #define INS(x) inserter(x,x.begin()) #define FOR(i,j,k) for(int i=j;i<=k;i++) #define MAXN 1005 #define MAXM 40005 #define INF 0x3fffffff #define PB push_back #define MP make_pair #define X first #define Y second #define lc (k<<1) #define rc ((k<<1)1) using namespace std; typedef long long LL; int i,j,k,n,m,x,y,T,ans[10005],big,cas,num,len; bool flag; int sum,wat[10005]; vector <int> fac[10005]; void GetFact(int size) { for (int i=1;i<=size;i++) { for (int j=i;j<=size;j+=i) { fac[j].push_back(i); } } } int main() { GetFact(10000); while (~scanf("%d",&n)) { memset(wat,0,sizeof(wat)); memset(ans,0,sizeof(ans)); for (i=1;i<=n;i++) { scanf("%d",&x); for (j=0;j<fac[x].size();j++) { int u=fac[x][j]; if (wat[u]) { k=wat[u]; ans[k]=i; wat[u]=0; } } wat[x]=i; } sum=0; for (i=1;i<=n;i++) { sum+=ans[i]; } printf("%d\n",sum); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zhyfzy/p/4458618.html