分块

数列分块入门 1

比较简单的分块入门题,整块维护一个区间加的 \(tag\) ,散块长度肯定不超过 \(\sqrt n\) 直接暴力加,询问的时候加上区间 \(tag\) 即可。

#include<iostream>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=5e4+5;
int bel[N],l[N],r[N];
ll a[N],tag[N];
int n,Bel;
inline int read()
{
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{if(ch=='-')  w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')
	{s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
void build()
{
	for(int i=1;i<=Bel;++i)		l[i]=(i-1)*Bel+1,r[i]=i*Bel;
	r[Bel]=n;
	for(int i=1;i<=Bel;++i)		
		for(int j=l[i];j<=r[i];++j)
			bel[j]=i;
	return ;
}
void update(int x,int y,int v)
{
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i) 	a[i]+=v;
		return ;
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)  a[i]+=v;
		for(int i=l[bel[y]];i<=y;++i)  a[i]+=v;
		for(int i=bel[x]+1;i<=bel[y]-1;++i)  tag[i]+=v;
		return ; 
	}
}
ll query(int x)
{
	return a[x]+tag[bel[x]];
}
int main()
{
	n=read();
	Bel=sqrt(n);
	build();
	for(int i=1;i<=n;++i)  a[i]=read();
	for(int i=1;i<=n;++i)
	{
		int op=read(),l=read(),r=read(),c=read();
		if(op==0)  update(l,r,c);
		if(op==1)  printf("%lld\n",query(r)); 
	}
	Byrespect_lowsmile;
}

数列分块入门 2

#include<iostream>
#include<algorithm>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=5e4+5;
int a[N],l[N],r[N],bel[N],tag[N],sq[N];
int n,Bel;
inline int read()
{
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{if(ch=='-') w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')
	{s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
void build()
{
	for(int i=1;i<=Bel;++i)  l[i]=(i-1)*Bel+1,r[i]=i*Bel;
	r[Bel]=n;
	for(int i=1;i<=Bel;++i)  sort(sq+l[i],sq+r[i]+1);
	for(int i=1;i<=Bel;++i)
		for(int j=l[i];j<=r[i];++j)
			bel[j]=i;
	return ;
}
void rebuild(int x)
{
	for(int i=l[x];i<=r[x];++i)   sq[i]=a[i];
	sort(sq+l[x],sq+r[x]+1);
}
void update(int x,int y,int v)
{
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i)  a[i]+=v;
		rebuild(bel[x]);
		return ;
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)  a[i]+=v;
		rebuild(bel[x]);
		for(int i=l[bel[y]];i<=y;++i)  a[i]+=v;
		rebuild(bel[y]);
		for(int i=bel[x]+1;i<=bel[y]-1;++i)  tag[i]+=v;
		return ;
	}
}
int query(int x,int y,int v)
{
	int res=0;
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i)  
			if(a[i]+tag[bel[i]]<v*v)  res++;
		return res;
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)	
			if(a[i]+tag[bel[i]]<v*v)  res++;
		for(int i=l[bel[y]];i<=y;++i)
			if(a[i]+tag[bel[i]]<v*v)  res++;
		for(int i=bel[x]+1;i<=bel[y]-1;++i)
		{
			int pos=lower_bound(sq+l[i],sq+r[i]+1,v*v-tag[i])-sq;
			res+=pos-l[i];
		}
		return res;
	}
}
int main()
{
//	freopen("fk.in","r",stdin);
//	freopen("fk.out","w",stdout);
	n=read();
	Bel=sqrt(n);
	for(int i=1;i<=n;++i)  a[i]=read(),sq[i]=a[i];
	build();
	for(int i=1;i<=n;++i)
	{
		int op=read(),l=read(),r=read(),c=read();
		if(op==0)  update(l,r,c);
		if(op==1)  printf("%d\n",query(l,r,c));
	}
	Byrespect_lowsmile;
}

数列分块入门 3

#include<iostream>
#include<algorithm>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=1e5+5;
int a[N],l[N],r[N],bel[N],tag[N],sq[N];
int n,Bel;
inline int read()
{
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{if(ch=='-') w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')
	{s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
void build()
{
	for(int i=1;i<=Bel;++i)  l[i]=(i-1)*Bel+1,r[i]=i*Bel;
	r[Bel]=n;
	for(int i=1;i<=Bel;++i)  sort(sq+l[i],sq+r[i]+1);
	for(int i=1;i<=Bel;++i)
		for(int j=l[i];j<=r[i];++j)
			bel[j]=i;
	return ;
}
void rebuild(int x)
{
	for(int i=l[x];i<=r[x];++i)   sq[i]=a[i];
	sort(sq+l[x],sq+r[x]+1);
}
void update(int x,int y,int v)
{
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i)  a[i]+=v;
		rebuild(bel[x]);
		return ;
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)  a[i]+=v;
		rebuild(bel[x]);
		for(int i=l[bel[y]];i<=y;++i)  a[i]+=v;
		rebuild(bel[y]);
		for(int i=bel[x]+1;i<=bel[y]-1;++i)  tag[i]+=v;
		return ;
	}
}
int query(int x,int y,int v)
{
	int res=-1;
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i)
		{
			if(a[i]+tag[bel[i]]<v)  res=max(res,a[i]+tag[bel[i]]);
			if(res==v-1)  break;
		}
		return res;
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)
		{
			if(a[i]+tag[bel[i]]<v)  res=max(res,a[i]+tag[bel[i]]);
			if(res==v-1)  return res;
		}
		for(int i=l[bel[y]];i<=y;++i)
		{
			if(a[i]+tag[bel[i]]<v)  res=max(res,a[i]+tag[bel[i]]);
			if(res==v-1)  return res;
		}
		for(int i=bel[x]+1;i<=bel[y]-1;++i)
		{
			if(sq[l[i]]+tag[i]>=v)  continue;
			int pos=lower_bound(sq+l[i],sq+r[i]+1,v-tag[i])-sq;
			res=max(res,sq[pos-1]+tag[bel[pos-1]]);
			if(res==v-1)  return res;
		}
		return res;
	}
}
int main()
{
	//freopen("fk.in","r",stdin);
	//freopen("fk.out","w",stdout);
	n=read();
	Bel=sqrt(n);
	for(int i=1;i<=n;++i)  a[i]=read(),sq[i]=a[i];
	build();
	for(int i=1;i<=n;++i)
	{
		int op=read(),l=read(),r=read(),c=read();
		if(op==0)  update(l,r,c);
		if(op==1)  printf("%d\n",query(l,r,c));
	}
	Byrespect_lowsmile;
}

数列分块入门 4

#include<iostream>
#include<algorithm>
#include<cmath>
#define away using
#define from namespace
#define OI std
#define Byrespect_lowsmile return 0
#define ll long long
away from OI;
const int N=5e4+5;
int n,Bel,q;
int l[N],r[N],bel[N];
ll sum[N],tag[N],a[N];
inline int read()
{
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{if(ch=='-') w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')
	{s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
void build()
{
	for(int i=1;i<=Bel;++i)  
		l[i]=(i-1)*Bel+1,r[i]=i*Bel;
	r[Bel]=n;
	for(int i=1;i<=Bel;++i)
		for(int j=l[i];j<=r[i];++j)
			sum[i]+=a[j],bel[j]=i;
	return ;
}
void update(int x,int y,int v)
{
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i)  a[i]+=v,sum[bel[i]]+=v;
		return ;
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)  a[i]+=v,sum[bel[i]]+=v;
		for(int i=l[bel[y]];i<=y;++i)  a[i]+=v,sum[bel[i]]+=v;
		for(int i=bel[x]+1;i<=bel[y]-1;++i)  tag[i]+=v;
		return ;
	}
}
ll query(int x,int y,int c)
{
	ll res=0;
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i)	res+=a[i]+tag[bel[i]];
		return (res%(c+1));
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)	res+=a[i]+tag[bel[i]];
		for(int i=l[bel[y]];i<=y;++i)   res+=a[i]+tag[bel[i]];
		for(int i=bel[x]+1;i<=bel[y]-1;++i)  res+=sum[i]+tag[i]*(r[i]-l[i]+1);
		return (res%(c+1));
	}
}
int main()
{
	//freopen("fk.in","r",stdin);
	//freopen("fk.out","w",stdout);
	n=read();
	Bel=sqrt(n);
	for(int i=1;i<=n;++i)  a[i]=read();
	build();
	for(int i=1;i<=n;++i)
	{
		int op=read(),l=read(),r=read(),c=read();
		if(op==0)  update(l,r,c);
		if(op==1)  printf("%lld\n",query(l,r,c));
	}
	Byrespect_lowsmile;
}

数列分块入门 5

#include<iostream>
#include<cmath>
#define Byrespect_lowsmile return 0
#define away using
#define form namespace
#define OI std
away form OI;
const int N=5e4+5;
typedef long long ll;
int l[N],r[N],bel[N],tag[N],a[N];
ll sum[N];
int n,Bel;
inline int read()
{
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{if(ch=='-')  w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')
	{s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
void build()
{
	for(int i=1;i<=Bel;++i)  l[i]=(i-1)*Bel+1,r[i]=i*Bel;
	r[Bel]=n;
	for(int i=1;i<=Bel;++i)
		for(int j=l[i];j<=r[i];++j)
		{
			sum[i]+=a[j],bel[j]=i;
			if(a[j]>1)  tag[i]=1;
		}
	return ;
}
void rebuild(int num)
{
	sum[num]=tag[num]=0;
	for(int i=l[num];i<=r[num];++i)		
	{
		sum[num]+=a[i];
		if(a[i]>1)  tag[num]=1;
	}
	return ;
}
void update(int x,int y)
{
	if(bel[x]==bel[y])
	{
		if(!tag[bel[x]])  return ;
		for(int i=x;i<=y;++i)	sum[bel[i]]-=a[i],a[i]=sqrt(a[i]),sum[bel[i]]+=a[i];
		rebuild(bel[x]);
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)	a[i]=sqrt(a[i]);
		rebuild(bel[x]);
		for(int i=l[bel[y]];i<=y;++i)	a[i]=sqrt(a[i]);
		rebuild(bel[y]);
		for(int i=bel[x]+1;i<=bel[y]-1;++i)  
		{
			if(!tag[i])  continue;
			for(int j=l[i];j<=r[i];++j)  a[j]=sqrt(a[j]);
			rebuild(i);
		}
	}
}
ll query(int x,int y)
{
	ll res=0;
	if(bel[x]==bel[y])
	{
		for(int i=x;i<=y;++i)  res+=a[i];
		return res;
	}
	else
	{
		for(int i=x;i<=r[bel[x]];++i)	res+=a[i];
		for(int i=l[bel[y]];i<=y;++i)	res+=a[i];
		for(int i=bel[x]+1;i<=bel[y]-1;++i)	res+=sum[i];
		return res;
	}
}
int main()
{
	//freopen("fk.in","r",stdin);
	//freopen("fk.out","w",stdout);
	n=read();
	Bel=sqrt(n);
	for(int i=1;i<=n;++i)  a[i]=read();
	build();
	for(int i=1;i<=n;++i)
	{
		int op=read(),l=read(),r=read(),c=read();
		if(op==0)	update(l,r);
		if(op==1)   printf("%lld\n",query(l,r));
	}
	Byrespect_lowsmile;
}
posted @ 2023-01-08 21:49  respect_lowsmile  阅读(15)  评论(0编辑  收藏  举报