zoukankan      html  css  js  c++  java
  • 分块讲解

    临近NOIP,我要复习各种学过的算法,先从暴力开始吧!

    分块就是把一个待求的序列分成√n块.之后暴力查找。分整块和散块两部分。所有信息在当前结点和块内同时维护。每次查询O(3*√n)。修改不一定。一般是O(1)--O(√n) 之间。

    这就是分块,原理及其简单。但写起来需要考虑一些细节。

    比如:洛谷P1816 忠诚 求区间最小值问题。

    我们还是可以把查询分成整块和散块两种,预处理每块内最小值与每个数在哪个块。这样方便O(1)查询。

    帖代码:

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    #define N 100010
    int n,Q;
    int belong[N];
    int minn[400];
    int a[N];
    int block,ans;
    int query(int x,int y)
    {
        int minx=0x3f3f3f3f;
        for(int i=x;i<=min(belong[x]*block,y);i++)
            minx=min(minx,a[i]);
        if(belong[x]!=belong[y])
            for(int i=(belong[y]-1)*block+1;i<=y;i++)
                minx=min(minx,a[i]);
        for(int i=belong[x]+1;i<belong[y];i++)
            minx=min(minx,minn[i]);
        return minx;
    }
    int main()
    {
        memset(minn,0x3f,sizeof(minn));
        scanf("%d%d",&n,&Q);
        block=sqrt(n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            belong[i]=(i-1)/block+1;
            minn[belong[i]]=min(a[i],minn[belong[i]]);
        }
        for(int i=1;i<=Q;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            ans=query(x,y);
            printf("%d ",ans);
        }
    }

    细节需要自己思考!

  • 相关阅读:
    将一个单向链表逆序
    高精度加法
    从反汇编的角度看引用和指针的区别
    冒泡排序
    josephus(约瑟夫)问题
    获取每个进程可打开的最大文件数量
    AIX免费终端的获取
    [转] Linux应用层的定时器Timer
    POD(plain old data)
    char与wchar_t的区别
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/9800986.html
Copyright © 2011-2022 走看看