题意:给出一段序列>>q个询问>>每个询问>>给出a,b,求sigam(arr[a],arr[a+b],arr[a+2*b].....)
思路: 平方分割并不仅仅用于分块>>>还可以用于计算
blo=sqrt(n)
对b进行排序
当b大于blo的时候直接暴力计算>>
当b小于blo的时候>>暴力>>计算>>运用dp的思路 对于同一个b,不同的a可以o(n)被处理出来>>>
总的复杂度大约是 q*sqrt(n);
#include<bits/stdc++.h> using namespace std; const int N=3e5+10; typedef long long ll; int n,q,a,b,blo,arr[N]; struct node{int a,b,id;}qq[N]; ll ans[N],dp[N]; bool cmp(node a,node b){ if(a.b!=b.b) return a.b>b.b; return a.a<b.a; } int main(){ scanf("%d",&n);blo=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&arr[i]); scanf("%d",&q); for(int i=1;i<=q;i++){ scanf("%d%d",&qq[i].a,&qq[i].b);qq[i].id=i; } sort(qq+1,qq+q+1,cmp); int n_b=-1; for(int i=1;i<=q;i++){ node nn=qq[i]; if(nn.b>=blo){ for(int i=nn.a;i<=n;i+=nn.b) ans[nn.id]+=arr[i]; } else{ if(nn.b!=n_b||dp[nn.a]==0){ for(int j=n;j>=1;j--){ if(j+nn.b>n) dp[j]=arr[j]; else dp[j]=dp[j+nn.b]+arr[j]; } n_b=nn.b; } ans[nn.id]=dp[nn.a]; } } for(int i=1;i<=q;i++){ printf("%I64d\n",ans[i]); } return 0; }