zoukankan      html  css  js  c++  java
  • 洛谷2801教主的魔法(分块)

    刚学习了分块,写篇题解庆祝一下qwq

    分块的核心思想是:把一段连续的区间分成若干块,这样当你询问的区间跨过了一块,原本 O ( n ) 的复杂度会降为 O ( 1 ) 或 O ( log ) ,其他零散的部分就暴力,这样就降低了一次询问的复杂度,于是就可以舒服的切掉线段树不能做的题了qwq

    分块的建立代码:

    void build(){//b=belong , le=length , k=块
        le=sqrt(n);
        k=n/le;
        if(le*le<n) k++;
        for(int i=1;i<=n;i++) b[i]=(i-1)/le+1,d[i]=a[i];
        for(int i=1;i<=k;i++) l[i]=(i-1)*le+1,r[i]=i*le;
        r[k]=n;
        //接下来是一个块中需要存储的信息
    }
    

    接下来讲一讲洛谷2801这道傻逼分块题:


    题目描述

    教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。

    每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)

    CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。

    WD巨懒,于是他把这个回答的任务交给了你。

    输入输出格式

    输入格式:

    第1行为两个整数N、Q。Q为问题数与教主的施法数总和。

    第2行有N个正整数,第i个数代表第i个英雄的身高。

    第3到第Q+2行每行有一个操作:

    (1) 若第一个字母为“M”,则紧接着有三个数字L、R、W。表示对闭区间 [L, R] 内所有英雄的身高加上W。

    (2) 若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R] 内有多少英雄的身高大于等于C。

    输出格式:

    对每个“A”询问输出一行,仅含一个整数,表示闭区间 [L, R] 内身高大于等于C的英雄数。

    输入输出样例

    输入样例#1:

     5 3
     1 2 3 4 5
     A 1 5 4
     M 3 5 1
     A 1 5 4
    

    输出样例#1:

     2
     3
    

    (Solution:)

    对于每一块,你需要的只是将元素存到另一个d数组并对其排序

    对于修改,多余的部分暴力,再重新放到d数组排一次序;中间部分,对每一块开一个p数组,表示这一块的所有元素应当加上的值,因为重新修改排序后不影响元素在块中位置,所以不必全部修改

    对于询问,多余的部分暴力,中间部分因为有序,所以可以二分查找

    贴代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1000010,M=1010;
    inline int read(){
        int f=1,w=0;char c=0;
        while(!isdigit(c))
        {
            if(c=='-') f=-1;
            c=getchar();
        }
        while(isdigit(c)) w=w*10+(c^48),c=getchar();
        return f*w;
    }
    int n,m,k,le,l[M],r[M],a[N],b[N],d[N],p[M];
    void build(){
        le=sqrt(n);
        k=n/le;
        if(le*le<n) k++;
        for(int i=1;i<=n;i++) b[i]=(i-1)/le+1,d[i]=a[i];
        for(int i=1;i<=k;i++) l[i]=(i-1)*le+1,r[i]=i*le;
        r[k]=n;
        for(int i=1;i<=k;i++) sort(d+l[i],d+r[i]+1);
    }
    void change(int la,int lb,int v){
        int ba=b[la],bb=b[lb];
        if(ba==bb)
        {
            for(int i=la;i<=lb;i++) a[i]+=v;
            for(int i=l[ba];i<=r[ba];i++) d[i]=a[i];
            sort(d+l[la],d+r[lb]+1);
        }
        else
        {
            for(int i=la;i<=r[ba];i++) a[i]+=v;
            for(int i=l[ba];i<=r[ba];i++) d[i]=a[i];
            sort(d+l[ba],d+r[ba]+1);
            for(int i=l[bb];i<=lb;i++) a[i]+=v;
            for(int i=l[bb];i<=r[bb];i++) d[i]=a[i];
            sort(d+l[bb],d+r[bb]+1);
            for(int i=ba+1;i<=bb-1;i++) p[i]+=v;
        }
    }
    int ask(int la,int lb,int c){
        int ans=0,ba=b[la],bb=b[lb];
        if(ba==bb)
        {
            for(int i=la;i<=lb;i++)
                if(a[i]+p[ba]>=c) ans++;
        }
        else
        {
            for(int i=la;i<=r[ba];i++)
                if(a[i]+p[ba]>=c) ans++;
            for(int i=l[bb];i<=lb;i++)
                if(a[i]+p[bb]>=c) ans++;
            for(int i=ba+1;i<=bb-1;i++)
            {
                int ll=l[i],rr=r[i],res=0,mid;
                while(ll<=rr)
                {
                    mid=(ll+rr)>>1;
                    if(d[mid]+p[i]>=c)
                        rr=mid-1,res=r[i]-mid+1;
                    else ll=mid+1;
                }
                ans+=res;
            }
        }
        return ans;
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        build();
        while(m--)
        {
            char c;cin>>c;
            int x=read(),y=read(),z=read();
            if(c=='A') printf("%d
    ",ask(x,y,z));
            else change(x,y,z);
        }
        return 0;
    }
    
  • 相关阅读:
    深入理解is_callable和method_exists
    php数据加密及数据存储和传输
    yii2深入理解之内核解析
    细说 unicode 、utf-8 、utf-16、ascii 、gbk 、gb2312
    RESTful API架构和oauth2.0认证机制(概念版)
    深入理解yii2之RBAC(模块化系统)
    yii rbac
    Yii2 设计模式
    深入理解PHP数组函数和预定义接口
    PHP 代码规范、流程规范、git规范
  • 原文地址:https://www.cnblogs.com/ajy-shi-cj-zui-cai/p/10385611.html
Copyright © 2011-2022 走看看