[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

原文地址:https://www.cnblogs.com/ghostcai/p/9247438.html