CodeForces 103D Time to Raid Cowavans 分块+dp

先对b从小到大sort,判断b是不是比sqrt(n)大,是的话就直接暴力,不是的话就用dp维护一下

dp【i】表示以nb为等差,i为起点的答案,可以节省nb相同的情况

#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1

using namespace std;

const double g=10.0,eps=1e-9;
const int N=300000+10,maxn=1000000+10,inf=0x3f3f3f;

int n,m;
ll ans[N],dp[N],w[N];
struct node{
    int a,b,id;
}c[N];
bool comp(node x,node y)
{
    if(x.b!=y.b)return x.b<y.b;
    return x.a<y.a;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%I64d",&w[i]);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&c[i].a,&c[i].b);
        c[i].id=i;
    }
    sort(c+1,c+m+1,comp);
    int nb=0;
    for(int i=1;i<=m;i++)
    {
        if(c[i].b>sqrt(0.5+n))
        {
            for(int j=c[i].a;j<=n;j+=c[i].b)
                ans[c[i].id]+=w[j];
        }
        else
        {
           if(c[i].b!=nb||dp[c[i].a]==0)
           {
               for(int j=n;j>=1;j--)
               {
                   if(j+c[i].b<=n)dp[j]=dp[j+c[i].b]+w[j];
                   else dp[j]=w[j];
               }
           }
           ans[c[i].id]=dp[c[i].a];
           nb=c[i].b;
        }
    }
    for(int i=1;i<=m;i++)
        printf("%I64d
",ans[i]);
    return 0;
}
/****************
5
3 2 4 5 6
8
4 2
3 1
3 5
3 4
3 5
5 5
4 4
5 3
****************/
View Code
原文地址:https://www.cnblogs.com/acjiumeng/p/7646625.html