题意:
询问 下标满足 a + b * k 的和是多少。
题解:
将询问分块。
将b >= blo直接算出答案。
否则存下来。
存下来之后,对于每个b扫一遍数组,然后同时处理相同b的询问。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) #define Show(x) cout << x << ' '; typedef pair<int,int> pll; const int INF = 0x3f3f3f3f; const LL mod = (int)1e9+7; const int N = 3e5 + 100; int n, m, k, p; int w[N]; LL tot[N]; LL ans[N]; struct Node{ int a, b, id; }q[N]; bool cmp(Node x1, Node x2){ return x1.b < x2.b; } int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &w[i]); scanf("%d", &p); k = sqrt(n); int t = 0, a, b; LL tmp; for(int i = 1; i <= p; i++){ scanf("%d%d", &a, &b); if(b >= k){ tmp = 0; for(int i = a; i <= n; i += b) tmp += w[i]; ans[i] = tmp; } else { q[t].a = a; q[t].b = b; q[t].id = i; t++; } } sort(q,q+t,cmp); for(int i = 0; i < t; i++){ if(i == 0 || q[i].b != q[i-1].b){ b = q[i].b; for(int i = n; i >= 1; i--){ if(i+b > n) tot[i] = w[i]; else tot[i] = tot[i+b] + w[i]; } } ans[q[i].id] = tot[q[i].a]; } for(int i = 1; i <= p; i++){ printf("%I64d ", ans[i]); } return 0; }