先对b从小到大sort,判断b是不是比sqrt(n)大,是的话就直接暴力,不是的话就用dp维护一下
dp【i】表示以nb为等差,i为起点的答案,可以节省nb相同的情况
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-9; const int N=300000+10,maxn=1000000+10,inf=0x3f3f3f; int n,m; ll ans[N],dp[N],w[N]; struct node{ int a,b,id; }c[N]; bool comp(node x,node y) { if(x.b!=y.b)return x.b<y.b; return x.a<y.a; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%I64d",&w[i]); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&c[i].a,&c[i].b); c[i].id=i; } sort(c+1,c+m+1,comp); int nb=0; for(int i=1;i<=m;i++) { if(c[i].b>sqrt(0.5+n)) { for(int j=c[i].a;j<=n;j+=c[i].b) ans[c[i].id]+=w[j]; } else { if(c[i].b!=nb||dp[c[i].a]==0) { for(int j=n;j>=1;j--) { if(j+c[i].b<=n)dp[j]=dp[j+c[i].b]+w[j]; else dp[j]=w[j]; } } ans[c[i].id]=dp[c[i].a]; nb=c[i].b; } } for(int i=1;i<=m;i++) printf("%I64d\n",ans[i]); return 0; } /**************** 5 3 2 4 5 6 8 4 2 3 1 3 5 3 4 3 5 5 5 4 4 5 3 ****************/