• [LOJ] 分块九题 3


    https://loj.ac/problem/6279

    区间修改,区间查询前驱。

    TLE无数,我觉得这代码最精髓的就是block=1000。
    谜一样的1000。

    两个启示:

    1. 块内可以维护数据结构,比如set
    2. 可以换换块大小,自造数据测试时间
    //Stay foolish,stay hungry,stay young,stay simple
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<set>
    #define R register
    using namespace std;
    
    
    const int nINF=-(1<<29);
    const int MAXN=500005;
    
    set<int> b[1000];
    
    void Out(int x)  
    {  
        if(x<0)  
        {  
            putchar('-');x=-x;  
        }  
        if(x>9)Out(x/10);  
        putchar(x%10+'0');  
    }  
    
    inline int read_d(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c)) f=c=='-'?-1:1;
        while(isdigit(c)){
            ret*=10;ret+=c-'0';
            c=getchar();
        }
        return f*ret;
    }
    
    int n;
    
    int a[MAXN],inc[MAXN],l[MAXN],
        r[MAXN],bl[MAXN];
    int block,num;
    
    void reset(int id){
        b[id].clear();
        for(R int i=l[id];i<=r[id];i++) b[id].insert(a[i]); 
    } 
    
    void build(){
    //    block=sqrt(n);
    //    block>>=1;
        block=1000;//玄学?!?!?!?!? 
        num=n/block;
        if(n%block) num++;
        for(int i=1;i<=n;i++){
            l[i]=(i-1)*block+1;
            r[i]=i*block;
        }
        r[num]=n;
        for(R int i=1;i<=n;i++)
            bl[i]=(i-1)/block+1;
        for(R int i=1;i<=n;i++) b[bl[i]].insert(a[i]); 
    }
    
    void updata(int x,int y,int w){
        if(bl[x]==bl[y]){
            for(int i=x;i<=y;i++)
                b[bl[i]].erase(a[i]),a[i]+=w,b[bl[i]].insert(a[i]); 
            return;
        }
        for(R int i=x;i<=r[bl[x]];i++){
            b[bl[i]].erase(a[i]);
            a[i]+=w;
            b[bl[i]].insert(a[i]);
        }
        for(R int i=bl[x]+1;i<=bl[y]-1;i++) 
            inc[i]+=w;
        for(R int i=l[bl[y]];i<=y;i++){
            b[bl[i]].erase(a[i]);
            a[i]+=w;
            b[bl[i]].insert(a[i]);
        }
    }
    
    int query(int x,int y,int w){
        int ret=nINF;
        if(bl[x]==bl[y]){
            ret=-1;
            for(int i=x;i<=y;i++){
                int v=a[i]+inc[bl[i]];
                if(v<w) ret=max(ret,v);
            }
            return ret;     
        }
        for(R int i=x;i<=r[bl[x]];i++){
            int v=a[i]+inc[bl[i]];
            if(v<w) ret=max(ret,v);
        }
        for(R int i=l[bl[y]];i<=y;i++){
            int v=a[i]+inc[bl[i]];
            if(v<w) ret=max(ret,v);
        } 
        for(R int i=bl[x]+1;i<=bl[y]-1;i++){
            set<int>::iterator it = b[i].lower_bound(w-inc[i]);
            if(it==b[i].begin())continue;
            --it;
            ret = max(ret,*it+inc[i]);
        }
        return ret;
    }
    
    int main(){
    //  freopen("in.txt","r",stdin);
    //  freopen("test.txt","w",stdout);
        n=read_d();
        for(R int i=1;i<=n;i++) a[i]=read_d();
        build();
        for(R int i=1;i<=n;i++){
            int q,x,y,z;
            q=read_d();
            x=read_d();
            y=read_d();
            z=read_d();
            if(q==0) updata(x,y,z);
            else {
                int ans=query(x,y,z);
                if(ans==nINF) puts("-1");
                else Out(ans),putchar('
    ');
            }
        }
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247438.html

  • 相关阅读:
    百度网盘免费下载加速
    linux docker 知识点总结
    openwrt 支持 EC200T
    openwrt 如何添加新设备支持
    openwrt DEPEND
    menuconfig kconfig
    golang 汇编
    按值传递
    YAPI认证用户利用Mock功能远程代码执行事件通告
    携程持久化KV存储实践
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247438.html
Copyright © 2020-2023  润新知