• loj #6278. 数列分块入门 2


    题目

    题解

    区间修改,询问区间小于c的个数。分块排序,用vector。至于那个块的大小,好像要用到均值不等式
    我不太会。。。就开始一个个试,发现siz=sqrt(n)/4时最快!!!明天去学一下算分块复杂度的方法。
    

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    
    using namespace std;
    const int MAXN = 50005;
    const int N = 1005;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    vector<int> b[N];
    
    int n,siz;
    int a[MAXN],l[N],r[N];
    int num,bl[MAXN],inc[MAXN];
    
    inline void reset(int id){
        b[id].clear();
        for(register int i=l[id];i<=r[id];i++) b[id].push_back(a[i]);
        sort(b[id].begin(),b[id].end());
    }
    
    inline void build(){
        siz=sqrt(n);
        siz/log2(n);
        num=n/siz;
        if(n%siz) num++;
        for(register int i=1;i<=n;i++)
            bl[i]=(i-1)/siz+1;  
        for(register int i=1;i<=num;i++){
            l[i]=(i-1)*siz+1;
            r[i]=i*siz;
        }
        r[num]=n;
        for(register int i=1;i<=num;i++) reset(i);
    }
    
    inline void update(int ql,int qr,int w){
        if(bl[ql]==bl[qr]){
            for(register int i=ql;i<=qr;i++)
                a[i]+=w;
            reset(bl[ql]);
            return;
        }
        for(register int i=ql;i<=r[bl[ql]];i++)
            a[i]+=w;
        reset(bl[ql]);
        for(register int i=bl[ql]+1;i<bl[qr];i++)   
            inc[i]+=w;
        for(register int i=l[bl[qr]];i<=qr;i++)
            a[i]+=w;
        reset(bl[qr]);
    }
    
    inline int query(int ql,int qr,int c){
        int ret=0;
        if(bl[ql]==bl[qr]){
            for(register int i=ql;i<=qr;i++)
                ret+=(a[i]+inc[bl[i]]<c);
            return ret;
        }
        for(register int i=ql;i<=r[bl[ql]];i++)
            ret+=(a[i]+inc[bl[i]]<c);
        for(register int i=l[bl[qr]];i<=qr;i++)
            ret+=(a[i]+inc[bl[i]]<c);
        for(register int i=bl[ql]+1;i<bl[qr];i++){
            int tar=c-inc[i];
            ret+=lower_bound(b[i].begin(),b[i].end(),tar)-b[i].begin();
        }
        return ret;
    }
    
    int main(){
        n=rd();
        for(register int i=1;i<=n;i++) a[i]=rd();
        build();
        for(register int i=1;i<=n;i++){
            int op,L,R,k;
            op=rd();L=rd();R=rd();k=rd();
            if(op==0)
                update(L,R,k);
            else
                printf("%d
    ",query(L,R,k*k));
        }
        return 0;
    }
  • 相关阅读:
    springMVC(5)---导入excel文件数据到数据库
    springMVC(4)---生成excel文件并导出
    springMVC(3)---利用pdf模板下载
    springMVC(1)---@RequestMapping详解
    springMVC(2)---获取前段数据
    【JS】---5 JS通过事件隐藏显示元素
    【JS】---4用JS获取地址栏参数方法
    【功能代码】---3 JS判断字符串是否包含某个字符串
    基于maven的ssm框架整合
    java提高(9)---HashMap解析
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9677036.html
Copyright © 2020-2023  润新知