题目大意:
给出一个序列 a a a,进行 Q Q Q次询问,每次询问 x , k x,k x,k:
求出: ∑ c = 0 c ∗ k + x < = n a x + c ∗ k \sum_{c=0}^{c*k+x<=n}{a_{x+c*k}} ∑c=0c∗k+x<=nax+c∗k
题目思路:
显然不太好维护这个东西。
但是可以考虑分块暴力一下,由于对于一个位置而言:
- 假设 k > s q r t ( n ) k \gt sqrt(n) k>sqrt(n),那么直接暴力即可,此时复杂度就是 ( n / k ) ≤ s q r t ( n ) (n/k) \le sqrt(n) (n/k)≤sqrt(n)
- 假设 k ≤ s q r t ( n ) k \le sqrt(n) k≤sqrt(n),此时下标集合的其实就是与 i i i在模 k k k相等同余系,所以可以直接暴力开一个 s q r t ( n ) ∗ s q r t ( n ) sqrt(n)*sqrt(n) sqrt(n)∗sqrt(n)的数组,代表对下标对 i i i取余为 k k k的数值总和,查询之后直接赋值就好了。
Code:
/*** keep hungry and calm CoolGuang! ***/
//#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 3e5+700;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
int block = 0;
ll sum[600][600];///对i取余为k的数量
ll a[maxn];
vector<pair<int,int>>v[maxn];
ll res[maxn];
int main(){
read(n);
for(int i=1;i<=n;i++) read(a[i]);
block = sqrt(n);
read(m);
for(int i=1;i<=m;i++){
int x,y;read(x);read(y);
v[x].push_back({
y,i});
}
for(int i=n;i>=1;i--){
for(int k=1;k<=block;k++) sum[k][i%k] += a[i];
for(auto x:v[i]){
int id = x.second,w = x.first;
if(w>block){
ll ans = 0;
for(int k=i;k<=n;k+=w) ans += a[k];
res[id] = ans;
}else res[id] = sum[w][i%w];
}
}
for(int i=1;i<=m;i++)
printf("%lld\n",res[i]);
return 0;
}
/***
7
6 6 2 7 4 2 5
7
1 3 6
2 1 2 2
***/