zoukankan      html  css  js  c++  java
  • 分块

    一直以为分块很高端,学完之后发现其实很简单了

    分块查找是折半查找和顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。

    分块就是将n个数分为每段有√n个数的多个区间,这样我们就可以在几乎O(√n)的时间内完成查找

    分块模版

    int block,num,belong[100100],le[100100],ri[100100],n;
    long long a[100100],max_sum[10100];
    void build()
    {     int i,j,k;
          block=sqrt(n);
          num=n/block;
          if(n%block)num++;
          for(i=1;i<=num;i++)
             le[i]=ri[i-1]+1,
             ri[i]=ri[i-1]+block;
          if(ri[num]>n)ri[num]=n;
          for(i=1;i<=n;i++)
             belong[i]=(i-1)/block+1;
          for(i=1;i<=num;i++)
             for(j=le[i];j<=ri[i];j++)
                max_sum[i]=max(max_sum[i],a[j]);
    }

    例题

    http://acm.uestc.edu.cn/#/problem/show/1324卿学姐与公主

    分块裸题,维护每一块的最大值

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int block,num,belong[100100],le[100100],ri[100100],n;
    long long a[100100],max_sum[10100];
    void build()
    {     int i,j,k;
          block=sqrt(n);
          num=n/block;
          if(n%block)num++;
          for(i=1;i<=num;i++)
             le[i]=ri[i-1]+1,
             ri[i]=ri[i-1]+block;
          if(ri[num]>n)ri[num]=n;
          for(i=1;i<=n;i++)
             belong[i]=(i-1)/block+1;
          for(i=1;i<=num;i++)
             for(j=le[i];j<=ri[i];j++)
                max_sum[i]=max(max_sum[i],a[j]);
    }
    void update(int p,int x)
    {     a[p]+=x;
          max_sum[belong[p]]=max(max_sum[belong[p]],a[p]);
    }
    long long ask(int L,int R)
    {     int i,j,k;
          long long maxn=0;
          if(belong[L]==belong[R]){
             for(i=L;i<=R;i++)
                maxn=max(maxn,a[i]);
             return maxn;
             }
             else {
                 for(i=L;i<=ri[belong[L]];i++)
                    maxn=max(maxn,a[i]);
                 for(i=belong[L]+1;i<=belong[R]-1;i++)
                    maxn=max(maxn,max_sum[i]);
                 for(i=le[belong[R]];i<=R;i++)
                    maxn=max(maxn,a[i]);
                 return maxn;
             }
    }
    int main()
    {     int q,i,j,k,x,y,p;
          cin>>n>>q;
          build();
          for(i=1;i<=q;i++){
              scanf("%d%d%d",&k,&p,&x);
              if(k==1)update(p,x);
                else printf("%lld ",ask(p,x));
          }
          return 0;
    }

     
  • 相关阅读:
    显示等待WebDriverWait+EC
    mac 上查看python3的各种安装路径
    layui弹窗全屏显示
    Mysql 一些细节方面解析(一)--MyISAM和InnoDB的主要区别和应用场景
    命令关闭tomcat
    xml 写sql语句文件头
    mysql update 修改多个字段and的语法问题
    zookeeper安装
    Java 基础--移位运算符
    SQL mybatis动态查询小结
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/8333867.html
Copyright © 2011-2022 走看看