D. Time to Raid Cowavans 分块+离线处理答案

D. Time to Raid Cowavans

题意:给出一段序列>>q个询问>>每个询问>>给出a,b,求sigam(arr[a],arr[a+b],arr[a+2*b].....)

思路: 平方分割并不仅仅用于分块>>>还可以用于计算

blo=sqrt(n)

对b进行排序

当b大于blo的时候直接暴力计算>>

当b小于blo的时候>>暴力>>计算>>运用dp的思路 对于同一个b,不同的a可以o(n)被处理出来>>>

总的复杂度大约是 q*sqrt(n);

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
int n,q,a,b,blo,arr[N];
struct node{int a,b,id;}qq[N];
ll ans[N],dp[N];
bool cmp(node a,node b){
    if(a.b!=b.b)
        return a.b>b.b;
    return a.a<b.a;
}
int main(){
    scanf("%d",&n);blo=sqrt(n);
    for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
    scanf("%d",&q);
    for(int i=1;i<=q;i++){
        scanf("%d%d",&qq[i].a,&qq[i].b);qq[i].id=i;
    }
    sort(qq+1,qq+q+1,cmp);
    int n_b=-1;
    for(int i=1;i<=q;i++){
        node nn=qq[i];
        if(nn.b>=blo){
            for(int i=nn.a;i<=n;i+=nn.b) ans[nn.id]+=arr[i];
        }
        else{
            if(nn.b!=n_b||dp[nn.a]==0){
                for(int j=n;j>=1;j--){
                    if(j+nn.b>n) dp[j]=arr[j];
                    else dp[j]=dp[j+nn.b]+arr[j];
                }
                n_b=nn.b;
            }
            ans[nn.id]=dp[nn.a];
        }
    }
    for(int i=1;i<=q;i++){
        printf("%I64d\n",ans[i]);
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/vainglory/p/9178423.html