Codeforces103D Time to Raid Cowavans
codeforces题解:
Let's solve this problem by offline. Read all queries and sort them by increasingb. After that there are many effective solutions but I tell you a most simple of them. Look at two following algorithms:
1. For each (a, b)-query calculate the answer by the simple way:
for(int i = a; i < n; i += b)
ans += a[i];2. Fix the value of b and calculate DP for all possible values ofa:
for(int i = n - 1; i >= 0; i--)
if (i + b >= n)
d[i] = a[i];
else
d[i] = d[i + b] + a[i];
Obvioulsy, the 1st algorithm is non-effective with little values ofb and the 2nd algorithm is non-effecitve with very different values ofb. Behold that it's impossible to generate the situation where allb's are so little and different simultaniously. There is a simple idea: we may solve the problem by 1st algo if values ofb are so large (if they are greater than c) and solve by 2nd algo if values of b are so small (if they are less of equal toc).
We need to sort our queries because of no reason to calculate DP of anyb more than once.
If we choose c equal to
that we will get a
complexity.
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
using namespace std;
typedef long long LL;
typedef double DB;
#define INF 2147483647
#define mms(_x, _y) memset(_x, _y, sizeof(_x));
#define rep(_x, _y, _z) for(int _x = _y; _x <= _z; _x++)
#define per(_x, _y, _z) for(int _x = _y; _x >= _z; _x--)
const int MOD=1e6+3;
const double pi = acos(-1.0);
const double E = exp(1.0);
const int M = 1e5+9;
struct x{
LL a,b,id,res;
}q[300009];
int cmp(const void* a,const void* b){
return (*(x*)a).b-(*(x*)b).b;
}
int cmpre(const void* a,const void* b){
return (*(x*)a).id-(*(x*)b).id;
}
LL n,p,mass[300009],bs[300009],re,f;
void Init(){
scanf("%I64d",&n);
rep(i,1,n)scanf("%I64d",&mass[i]);
scanf("%I64d",&p);
rep(i,0,p-1){
scanf("%I64d%I64d",&q[i].a,&q[i].b);
q[i].id=i;
}
}
void Solve(){
qsort(q,p,sizeof(q[0]),cmp);
f=-1;
rep(i,0,p-1){
if(q[i].b<520){
if(q[i].b==f)q[i].res=bs[q[i].a];
else{
f=q[i].b;
per(j,n,1){
if(j+f>n)bs[j]=mass[j];
else bs[j]=bs[j+f]+mass[j];
}
q[i].res=bs[q[i].a];
}
}
else{
re=0;
for(int j=q[i].a;j<=n;j+=q[i].b)re+=mass[j];
q[i].res=re;
}
}
qsort(q,p,sizeof(q[0]),cmpre);
rep(i,0,p-1)printf("%I64d\n",q[i].res);
}
int main(){
int _T = 1;
//scanf("%d",&_T);
while(_T--){
Init();
Solve();
}
return 0;
}