hdu 4961 Boring Sum n*logn
2014-08-20 16:08
330 查看
【题意】给n个数字 求每个数字 左边的数字中是其倍数的且下标最大 的数字*右边的倍数中是其倍数的且下标最小的数字 的和
或者说就是每个数 左边最近的倍数*右边最近的倍数 的和。
http://acm.hdu.edu.cn/showproblem.php?pid=4961
或者说就是每个数 左边最近的倍数*右边最近的倍数 的和。
http://acm.hdu.edu.cn/showproblem.php?pid=4961
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; int a[100002],b[100002],c[100002]; int vis[100002]; int main() { int n; while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); memset(vis,0,sizeof(vis)); //值i倍数且是在左边的中对应的最大下标 for(int i=1;i<=n;i++) { if(vis[a[i]]) b[i]=a[vis[a[i]]]; else b[i]=a[i]; for(int j=1;j<(int)sqrt((double)a[i])+1;j++) { if(a[i]%j==0) { vis[a[i]/j]=i; vis[j]=i; } }//更新的都是i右边的约数,因为i和i前面的都已经得出来了 。由于i是小到大,所有得到的值也是最大的。 } memset(vis,0,sizeof(vis)); //值i倍数且是在右边的对应的最小下标 for(int i=n;i>=1;i--) { if(vis[a[i]]) c[i]=a[vis[a[i]]]; else c[i]=a[i]; for(int j=1;j<(int)sqrt((double)a[i])+1;j++) { if(a[i]%j==0) { vis[a[i]/j]=i; vis[j]=i; } }//更新的都是i左边的约数的vis值,因为i和i后面的都已经得出来了。由于i是小到大,所以得到的值也是最小的 } __int64 ans=0; for(int i=1;i<=n;i++) ans+=(__int64 )b[i]*c[i]; printf("%I64d\n",ans); } return 0; }
相关文章推荐
- hdu 4961 Boring Sum【构造题】
- 【瞎搞】HDU 4961 Boring Sum
- HDU 4961 Boring Sum 暴力
- hdu 4961 Boring Sum
- hdu 4961 Boring Sum 2014 Multi-University Training Contest 9
- hdu 4961 Boring Sum
- HDU 4961 Boring Sum
- HDU 4961 Boring Sum 构造题
- HDU 4961 Boring Sum 因数分解
- HDU-4961 Boring Sum (模拟)
- HDU 4961 Boring Sum
- hdu 4961 Boring Sum 多校九
- hdu 4961 Boring Sum
- hdu 4961 Boring Sum
- hdu 4961 Boring Sum--2014 Multi-University Training Contest 9
- HDU - 4961 Boring Sum
- hdu 4961 Boring Sum
- 【瞎搞】HDU 4961 Boring Sum
- HDU 5875 Function(logn取模+二分rmq)
- 2014多校训练九(HDU 4960 HDU 4961 HDU 4965 HDU 4968 HDU 4969 HDU 4970)