题目链接:Boring Sum
题面:
5 1 4 2 3 9 0
136HintIn the sample, b1=1, c1=4, b2=4, c2=4, b3=4, c3=2, b4=3, c4=9, b5=9, c5=9, so b1 * c1 + b2 * c2 + … + b5 * c5 = 136.
解题:直接暴肯定不行。先预处理一下,将每个ai的值存在对应下标中。然后,寻找某个值时,只需遍历该值的倍数对应的vector寻找最接近的左边值和右边值。需注意的是当ai比较小的时候就直接寻找,以提高效率,这里边界设置为300。
代码:
#include <iostream> #include <vector> #include <cstdio> #include <cstring> using namespace std; int a[100000+10]; vector <int> store[100000+10]; int main() { int n,tmp,maxx,b,c,p,maa,mii; bool fla1,fla2; long long sum=0,bb,cc; while(scanf("%d",&n)&&n) { maxx=sum=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]>maxx) maxx=a[i]; } for(int i=0;i<=maxx;i++) store[i].clear(); for(int i=1;i<=n;i++) store[a[i]].push_back(i); for(int i=1;i<=n;i++) { fla1=false; fla2=false; if(a[i]<=300) { for(int j=i-1;j>=1;j--) { if(a[j]%a[i]==0) { p=j; fla1=true; break; } } if(fla1) { b=a[p]; } else b=a[i]; for(int j=i+1;j<=n;j++) { if(a[j]%a[i]==0) { p=j; fla2=true; break; } } if(fla2) { c=a[p]; } else c=a[i]; //cout<<"c"<<i<<": "<<c<<" b"<<i<<": "<<b<<endl; bb=b; cc=c; sum+=bb*cc; } else { maa=100005; mii=-1; tmp=a[i]; while(tmp<=maxx) { int si=store[tmp].size(); for(int k=0;k<si;k++) { if(store[tmp][k]>i) { if(store[tmp][k]<maa) maa=store[tmp][k]; } else if(store[tmp][k]<i) { if(store[tmp][k]>mii) mii=store[tmp][k]; } } tmp+=a[i]; } if(mii!=-1) { b=a[mii]; } else b=a[i]; if(maa!=100005) { c=a[maa]; } else c=a[i]; //cout<<"c"<<i<<": "<<c<<" b"<<i<<": "<<b<<endl; bb=b; cc=c; sum+=bb*cc; } } cout<<sum<<endl; } return 0; }