萌新刚学分块1ms,求调板子
查看原帖
萌新刚学分块1ms,求调板子
774854
qzmoot楼主2024/5/4 12:53

TLETLE

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int n,q,a[N];
int read()
{
	int x=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return  x;
}
int len,tot,b[N],l[800],r[800],id[N];
int ef(int le,int ri,int val)
{
	int as=0,nr=ri;
	while(le<=ri)
	{
		int mid=le+ri>>1;
		if(b[mid]>=val)
			ri=mid-1,as=nr-mid+1;
		else
			le=mid+1;
	}
	return as;
}
int query(int x,int y,int z)
{
	int res=0,nx=id[x],ny=id[y];
	if(nx==ny)
	{
		for(int i=x;i<=y;i++)
			if(b[i]>=z)
				res++;
		return res;
	}
	for(int i=x;i<=r[nx];i++)
		if(b[i]>=z)
			res++;
	for(int i=l[ny];i<=y;i++)
		if(b[i]>=z)
			res++;
	for(int i=nx+1;i<=ny;i++)
		res+=ef(l[i],r[i],z);
	return res;
}
void upd(int x,int y)
{
	a[x]=y;
	int bl=id[x];
	for(int i=l[bl];i<=r[bl];i++)
		b[i]=a[i];
	sort(b+l[bl],b+r[bl]+1);
}
int main()
{
	n=read();
	len=sqrt(n);
	tot=ceil(n*1.0/len);
	for(int i=1,cnt=1,idx=1;i<=n;cnt++,i++)
	{
		a[i]=b[i]=read();
		if(cnt==3)
			cnt=1,idx++;
		id[i]=idx;
	}
	for(int i=1,ll=i,rr=ll;i<tot;i++)
	{
		rr=ll+len-1;
		l[i]=ll;
		r[i]=rr;
		ll=rr+1;
		sort(b+l[i],b+r[i]+1);
	}
	l[tot]=r[tot-1]+1;
	r[tot]=n;
	q=read();
	while(q--)
	{
		int op=read();
		if(!op)
		{
			int x=read(),y=read(),z=read();
			printf("%d\n",query(x,y,z));
		}
		else
		{
			int x=read(),y=read();
			upd(x,y);
		}
	}
	return 0;
}
2024/5/4 12:53
加载中...