zoukankan      html  css  js  c++  java
  • Time to Raid Cowavans ( 非分块sqrt(n)算法 + 离线查询特性应用

    题意:给定数组c[n],及多组a,b ,求每一组的后缀和 c[a]+c[a+b]+c[a+2*b]+c[a+3*b].......

    分析:

     对于每一个b值 ,都可以在o(n)的复杂度内利用dp 求出该b下不同a值对应的后缀和sum[a]:

                     for( int j=n ;j>=1 ;j--){
                         if( j > n-q[i].b )sum[j] = a[j] ;
                         else sum[j] = sum[ j+q[i].b ] + a[j];
                     }

    dp一次后,对于不同a值的询问都是o(1)复杂度的;

    我们也可以暴力在o(n/b)的复杂度内对一组a,b求解:

                 while( q[i].a <=n){
                     ans[ q[i].id ]+=a[ q[i].a ];
                     q[i].a+=q[i].b;
                 }

    以sqrt(n)分界,b大于sqrt(n)暴力复杂度为o(sqrt(n)),可以接受;

    b小于sqrt(n)直接dp,最多有sqrt(n)个不同b值,复杂度为o( n*sqrt(n) ),可以接受;

    由于没有在线查询,即输入一组数据立即给出答案,我们可以对每一组(a,b)按b排序,b相同的一起处理,相同的b只用一次dp就够了,然后把每一次的结果存在ans[i]中,按查询顺序输出即可

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int sq , n ,m;
    
    ll  a[300000+500];
    ll  ans[300000+500] ,sum[300000+500];
    
    struct Query{
         int id, a ,b;
    } q[300000+500];
    
    bool cmp( const Query & a ,const Query & b){
          return a.b < b.b;
    }
    int main( ){
         scanf("%d" ,&n);
         sq = sqrt( n );
         for( int i=1 ;i<=n ;i++)
            scanf( "%I64d" ,&a[i]);
         scanf("%d" ,&m);
         for( int i=1 ;i<=m ;i++){
             q[i].id = i;
             scanf( "%d%d" ,&q[i].a ,&q[i].b);
         }
    
         q[0] . b=0;
    
         sort( q+1 ,q+1+m ,cmp);
         for( int i=1 ;i<=m ;i++){
             if( q[i] .b <sq){
                 if( q[i].b != q[i-1].b){
                     for( int j=n ;j>=1 ;j--){
                         if( j > n-q[i].b )sum[j] = a[j] ;
                         else sum[j] = sum[ j+q[i].b ] + a[j];
                     }
                 }
                 ans[ q[i].id ]=sum[ q[i].a ];
             }
             else {
                 ans[ q[i].id ] = 0;
                 while( q[i].a <=n){
                     ans[ q[i].id ]+=a[ q[i].a ];
                     q[i].a+=q[i].b;
                 }
             }
         }
    
         for( int i=1 ;i<=m ;i++)
            printf("%I64d
    " ,ans[i]);
         return 0;
    }
  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/-ifrush/p/10740244.html
Copyright © 2011-2022 走看看