其他分享
首页 > 其他分享> > 分块(优雅的暴力) 学习博客。。。持续更新

分块(优雅的暴力) 学习博客。。。持续更新

作者:互联网

学习参照以下两个博客:分块——优雅的暴力  分块入门1~9

分块入门1:

给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,单点查值。

//给定一个长为n的序列,以及n个操作,操作涉及区间加法,单点查值
#include<bits/stdc++.h>
using namespace std;
const int maxn = 50086;
int a[maxn],n,m;
int add[maxn];
int pos[maxn];//,sum[maxn];
int L[maxn],R[maxn];

inline void change(int l,int r,int d){
	int p = pos[l], q = pos[r];
	
	if(p==q)//如果要修改的区间在同一个块里面 
	    for(int i=l;i<=r;++i) a[i]+=d;
	    
	else {//如果要修改的区间不在同一个块里面 
		for(int i=p+1;i<=q-1;++i) add[i] += d;//直接给块赋值 
		for(int i=l;i<=R[p];i++) a[i]+=d;
		for(int i=L[q];i<=r;++i) a[i]+=d;
	}
} 
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	int t = sqrt(n);//分为t块 
	
	for(int i=1;i<=t;++i){//开始分块,完整块 
		L[i] = (i-1)*t + 1;
		R[i] = i*t; 
	}
	
	if(R[t]<n) t++,L[t]=R[t-1]+1,R[t]=n;//不完整块 

	for(int i=1;i<=t;i++){//每个元素在块的位置 
		for(int j=L[i];j<=R[i];j++){
			pos[j]=i;
		}
	}
	
	for(int i=1;i<=m;++i){
		int opt, l, r, c;
		cin>>opt;
		if(!opt) {
			cin>>l>>r>>c;
			change(l,r,c);
		}
		else {
			cin>>r;
			int q = pos[r];
			cout<<a[r] + add[q]<<endl;
		}
	}
 } 

 

 

 

 

 

 

标签:opt,长为,分块,int,pos,博客,优雅,maxn
来源: https://blog.csdn.net/qq_42129242/article/details/94735039