• 高级的暴力(一)——分块


    在某大佬的帮助下我今天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. }   
  • 相关阅读:
    faked 一个用于 mock 后端 API 的轻量工具
    分享开源 Markdown 编辑器 Mditor 的「桌面版」
    一个 MVC 框架以 MVVM 之「魂」复活了!
    简单的内存缓存模块
    Node 多进程并发控制小模块
    Confman
    用 Nokitjs 解决前端开发中的跨域问题
    LEK分布式日志系统搭建
    hello world2
    hello world!
  • 原文地址:https://www.cnblogs.com/LQ-double/p/5971332.html
Copyright © 2020-2023  润新知