zoukankan      html  css  js  c++  java
  • 高级的暴力(一)——分块

    在某大佬的帮助下我今天get到了分块

    简单来说分块就是可以把块分成某些奇怪的大小,使之达到优秀的复杂度。but我现在只会把块分成根号大小,然后我们修改一个点的

    信息时就可以顺便修改次点所在块的信息(O(1))。接着当我们查询[L,R]这段区间,的时候,对于中间的大块可以直接拿来用,对于两

    边不完整的块则直接暴力查询(都是根号n,)。

    差不多就这样,最后附上DCOJ 1324用分块过的代码

    [cpp] view plain copy
     
    1. #include<iostream>  
    2. #include<cstdio>  
    3. #include<cstring>  
    4. #include<algorithm>  
    5. #include<cmath>  
    6. using namespace std;  
    7. const int maxn=1e5+7;  
    8. int num,block,l[maxn],r[maxn],n,m,p,x,t,belong[maxn];  
    9. long long Max[maxn],a[maxn];  
    10. void build()  
    11. {  
    12.     block=sqrt(n);//块的太小   
    13.     num=n/block;  
    14.     if(n%block) num++;//块的个数,记得特判   
    15.     for(int i=1;i<=num;i++)  
    16.     {  
    17.         l[i]=(i-1)*block+1;  
    18.         r[i]=i*block;  
    19.     }//确定每个块的左右区间   
    20.       
    21.     r[num]=n;//不要忘记最右为n   
    22.     for(int i=1;i<=n;i++)    belong[i]=(i-1)/block+1;//确定每个 点所属的块   
    23.     for(int i=1;i<=num;i++)  
    24.        for(int j=l[i];j<=r[i];j++)  
    25.        Max[i]=max(Max[i],a[j]);//预处理   
    26. }  
    27. void update(int x,int date)//单点更改   
    28. {  
    29.     a[x]+=date;  
    30.     Max[belong[x]]=max(Max[belong[x]],a[x]);  
    31. }  
    32. long long ask(int x,int y)//区间查询   
    33. {  
    34.     long long ans=0;  
    35.     if(belong[x]==belong[y])  
    36.     {  
    37.         for(int i=x;i<=y;i++)  
    38.         {  
    39.             ans=max(ans,a[i]);  
    40.         }  
    41.         return ans;  
    42.     }//如果左右端点在同一块内则直接暴力查询   
    43.     for(int i=x;i<=r[belong[x]];i++)  
    44.     ans=max(ans,a[i]);  
    45.     for(int i=belong[x]+1;i<belong[y];i++)  
    46.     ans=max(ans,Max[i]);//如果左右端点需跨块,那么对于中间大块的信息直接使用  
    47.     for(int i=l[belong[y]];i<=y;i++)  
    48.     ans=max(ans,a[i]);// 两端不完整的的块暴力查询   
    49.     return ans;  
    50. }  
    51. int main()  
    52. {  
    53.     scanf("%d",&n);  
    54.     build();  
    55.     scanf("%d",&m);  
    56.     while(m--)  
    57.     {  
    58.         scanf("%d%d%d",&t,&p,&x);  
    59.         if(t==1) update(p,x);  
    60.         else printf("%lld ",ask(p,x));  
    61.     }  
    62.     return 0;  
    63. }   
  • 相关阅读:
    linux软件安装方式
    docker 安装 jenkins touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
    [ERR] Node goodsleep.vip:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    Linux 常用命令 服务器间scp 用户 export 创建文件、软连接
    redis 安装 集群 主从 哨兵 docker
    WPF密码框中禁止复制、粘贴
    Application 统计在线人数
    【转义字符】HTML 字符实体&lt; &gt: &amp;等
    SQL语句统计每天的数据
    正则表达式计算代码数
  • 原文地址:https://www.cnblogs.com/LQ-double/p/5971332.html
Copyright © 2011-2022 走看看