很容易想到根号分治,但是普通的根号分治空间开不下.
所以我们将询问离线,然后倒序处理即可.
code:
#include <bits/stdc++.h> #define M 550 #define N 300005 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,m,B; ll f[M][M],A[N],output[N]; struct query { int id,k; query(int id=0,int k=0):id(id),k(k){} }; struct Data { int id,pos; vector<query>v; }p[N]; int main() { int i,j; // setIO("input"); scanf("%d",&n); B=sqrt(n); for(i=1;i<=n;++i) { scanf("%lld",&A[i]); p[i].id=(i-1)/B+1; if(p[i].id!=p[i-1].id) p[i].pos=1; else p[i].pos=p[i-1].pos+1; } scanf("%d",&m); for(i=1;i<=m;++i) { int a,b; scanf("%d%d",&a,&b); if(b<B) p[a].v.push_back(query(i, b)); else { ll re=0; for(j=a;j<=n;j+=b) re+=A[j]; output[i]=re; } } for(i=n;i>=1;--i) { int cur=p[i].pos; for(j=1;j<B;++j) { f[p[i].pos][j]=A[i]; if(i+j<=n) { f[p[i].pos][j]+=f[p[i+j].pos][j]; } } for(j=0;j<p[i].v.size();++j) { output[p[i].v[j].id]=f[p[i].pos][p[i].v[j].k]; } } for(i=1;i<=m;++i) printf("%lld\n",output[i]); return 0; }
CF103D Time to Raid Cowavans 根号分治+离线
原文:https://www.cnblogs.com/guangheli/p/11642765.html