• 题解——loj6279 数列分块入门3 (分块)


    用set维护有序序列

    或许sort也可以,但这题的前驱定义是严格小于

    所以要去重

    然后就是记得自己打的加法tag在query的时候一定要算上

    话说这题数据有点fake啊忘了查询算上自己的标记了还有70

    然后还有玄学优化

    块的大小从( sqrt x )变成1000每个点能快300ms的样子qwq

    似乎原理是减少维护的set的个数吧

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <set>
    #include <cmath>
    using namespace std;
    const int MAXN = 101000;
    int n,sz,num,tag[MAXN],a[MAXN],belong[MAXN];
    set<int> b[105];
    void calbe(int n){
    	for(int i=1;i<=n;i++)
    		belong[i]=(i-1)/sz+1;
    }
    void reset(int x){
    	b[x].clear();
    	for(int i=(x-1)*sz+1;i<=min(x*sz,n);i++)
    		b[x].insert(a[i]);
    }
    void update(int l,int r,int w){
    	int xl=belong[l];
    	int xr=belong[r];
    	for(int i=l;i<=min(xl*sz,r);i++){
    		b[xl].erase(a[i]);
    		a[i]+=w;
    		b[xl].insert(a[i]);
    		}
    	if(xl!=xr){
    		for(int i=(xr-1)*sz+1;i<=r;i++){
    			b[xr].erase(a[i]);
    			a[i]+=w;
    			b[xr].insert(a[i]);
    		}
    	}
    	for(int i=xl+1;i<=xr-1;i++)
    		tag[i]+=w;
    }
    int query(int l,int r,int w){
    	int xl=belong[l];
    	int xr=belong[r];
    	int ans=-1;
    	for(int i=l;i<=min(r,xl*sz);i++)
    		if(a[i]<w-tag[xl]&&a[i]+tag[xl]>ans)
    			ans=a[i]+tag[xl];
    	if(xl!=xr){
    		for(int i=(xr-1)*sz+1;i<=r;i++)
    			 if(a[i]<w-tag[xr]&&a[i]+tag[xr]>ans)
    			 	ans=a[i]+tag[xr];
    	}
    	for(int i=xl+1;i<=xr-1;i++){
    		set<int> :: iterator it=b[i].lower_bound(w-tag[i]);
    		if(it==b[i].begin())
    			continue;
    		it--;
    		if(ans<(*it+tag[i]))
    			ans=*it+tag[i];
    	}
    	return ans;
    }
    int main(){
    	scanf("%d",&n);
    	sz=1000;
    	calbe(n);
    	num=n/sz;
    	if(n%sz)
    		num++;
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	for(int i=1;i<=num;i++){
    		reset(i);
    	} 
    	for(int i=1;i<=n;i++){
    		int opt,l,r,c;
    		scanf("%d %d %d %d",&opt,&l,&r,&c);
    		if(opt==0)
    			update(l,r,c);
    		else
    			printf("%d
    ",query(l,r,c));
    	}
    	return 0;
    }
  • 相关阅读:
    【Scala】看代码,初步了解Apply方法
    【Scala】通过简洁代码搞明白伴生关系、主构造器和辅助构造器的关系
    【Scala】关于集合的各种知识点
    【Scala】新手入门,基础语法概览
    C#中的异步多线程13 回调
    C#中的异步多线程12 轮询
    C#中的异步多线程11 等待直到结束
    C#中的异步多线程10 BackgroundWorker类
    C#中的异步多线程9 完整的GUI示例
    C#中的异步多线程8 Task.Yield
  • 原文地址:https://www.cnblogs.com/dreagonm/p/9507419.html
Copyright © 2020-2023  润新知