求调第二分块,悬关
查看原帖
求调第二分块,悬关
1041101
Aventurine_stone楼主2024/1/24 17:23
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int x=0;
	char c=getchar();
	while(c<'0'||c>'9')
		c=getchar();
	while(c>='0'&&c<='9')
	{
		x=(x<<3)+(x<<1)+(c-'0');
		c=getchar();
	}
	return x;
}
inline void write(int x)
{
	if(x>9)
		write(x/10);
	putchar(x%10+'0');
}
const int N=100010;
int n,m;
int a[N];
int fa[N],e[N];
int cha(int x)
{
	if(x==fa[x])
		return x;
	return fa[x]=cha(fa[x]);
}
int tl[320],tr[320],tmax[320],tag[320],td[N];
int ts[320][N],tt[320][N];
int q,idx;
void build(int l,int r)
{
	idx++;
	tl[idx]=l,tr[idx]=r;
	for(int i=l;i<=r;i++)
	{
		tmax[idx]=max(tmax[idx],a[i]);
		td[i]=idx;
		if(ts[idx][a[i]])
		{
			fa[i]=tt[idx][a[i]];
		}
		else
		{
			e[i]=a[i];
			fa[i]=i;
			tt[idx][a[i]]=i;
		}
		ts[idx][a[i]]++;
	}
	if(r==n)
		return ;
	build(l+q,min(r+q,n));
}
void change(int l,int r,int x)
{
	int st=td[l],ed=td[r];
	if(ed-st<=1)
	{
		for(int i=l;i<=r;i++)
		{
			int &y=ts[td[i]][e[cha(i)]];
			if(y>x)
			{
				if(ts[td[i]][e[cha(i)]-x])
				{
					fa[cha(i)]=fa[tt[td[i]][e[cha(i)]-x]];
					e[i]=0;
				}
				else
				{
					tt[td[i]][e[cha(i)]-x]=fa[cha(i)];
					e[i]-=x;
				}
				ts[td[i]][e[cha(i)]-x]+=y;
				tt[td[i]][e[cha(i)]]=0;
				y=0;
			}
		}
		tmax[st]=0;
		for(int i=tl[st];i<=tr[st];i++)
			tmax[st]=max(tmax[st],e[cha(i)]);
		if(st!=ed)
		{
			tmax[ed]=0;
			for(int i=tl[ed];i<=tr[ed];i++)
				tmax[ed]=max(tmax[ed],e[cha(i)]);
		}
	}
	else
	{
		for(int i=l;i<=tr[st];i++)//左 
		{
			int &y=ts[td[i]][e[cha(i)]];
			if(e[cha(i)]>x)
			{
				if(ts[td[i]][e[cha(i)]-x])
				{
					fa[cha(i)]=fa[tt[td[i]][e[cha(i)]-x]];
					e[cha(i)]=0;
				}
				else
				{
					tt[td[i]][e[cha(i)]-x]=fa[cha(i)];
					e[cha(i)]-=x;
				}
				ts[td[i]][e[cha(i)]-x]+=y;
				tt[td[i]][e[cha(i)]]=0;
				y=0;
			}
		}
		tmax[st]=0;
		for(int i=tl[st];i<=tr[st];i++)
			tmax[st]=max(tmax[st],e[cha(i)]);
		for(int i=tl[ed];i<=r;i++)//右 
		{
			int &y=ts[td[i]][e[cha(i)]];
			if(y>x)
			{
				if(ts[td[i]][e[cha(i)]-x])
				{
					fa[cha(i)]=fa[tt[td[i]][e[cha(i)]-x]];
					e[i]=0;
				}
				else
				{
					tt[td[i]][e[cha(i)]-x]=fa[cha(i)];
					e[i]-=x;
				}
				ts[td[i]][e[cha(i)]-x]+=y;
				tt[td[i]][e[cha(i)]]=0;
				y=0;
			}
		}
		tmax[ed]=0;
		for(int i=tl[ed];i<=tr[ed];i++)
			tmax[ed]=max(tmax[ed],e[cha(i)]);
		for(int i=st+1;i<=ed-1;i++)//整体
			if(tmax[i]>x)
				tag[i]+=x;
	}
}
int ask(int l,int r,int x)
{
	int st=td[l],ed=td[r];
	int s=0;
	if(ed-st<=1)
	{
		if(tag[st])
		{
			for(int i=tl[st];i<=tr[st];i++)
				if(e[cha(i)]>tag[st])
				{
					if(ts[st][e[cha(i)]-tag[st]])
					{
						fa[cha(i)]=fa[tt[st][e[cha(i)]-tag[st]]];
						e[i]=0;
					}
					else
					{
						tt[st][e[cha(i)]-tag[st]]=fa[cha(i)];
						e[i]-=tag[st];
					}
					ts[st][e[cha(i)]-tag[st]]+=ts[st][e[cha(i)]];
					tt[st][e[cha(i)]]=0;
					ts[st][e[cha(i)]]=0;
				}
			tmax[st]=0;
			for(int i=tl[st];i<=tr[st];i++)
				tmax[st]=max(tmax[st],e[cha(i)]);
		}
		if(st!=ed&&tag[ed])
		{
			for(int i=tl[ed];i<=tr[ed];i++)
				if(e[cha(i)]>tag[ed])
				{
					if(ts[ed][e[cha(i)]-tag[ed]])
					{
						fa[cha(i)]=fa[tt[ed][e[cha(i)]-tag[ed]]];
						e[i]=0;
					}
					else
					{
						tt[ed][e[cha(i)]-tag[ed]]=fa[cha(i)];
						e[i]-=tag[ed];
					}
					ts[ed][e[cha(i)]-tag[ed]]+=ts[ed][e[cha(i)]];
					tt[ed][e[cha(i)]]=0;
					ts[ed][e[cha(i)]]=0;
				}
			tmax[ed]=0;
			for(int i=tl[ed];i<=tr[ed];i++)
				tmax[ed]=max(tmax[ed],e[cha(i)]);
		}
		for(int i=l;i<=r;i++)
			if(e[cha(i)]==x)
				s++;
	}
	else
	{
		if(tag[st])
		{
			for(int i=tl[st];i<=tr[st];i++)
				if(e[cha(i)]>tag[st])
				{
					if(ts[st][e[cha(i)]-tag[st]])
					{
						fa[cha(i)]=fa[tt[st][e[cha(i)]-tag[st]]];
						e[i]=0;
					}
					else
					{
						tt[st][e[cha(i)]-tag[st]]=fa[cha(i)];
						e[i]-=tag[st];
					}
					ts[st][e[cha(i)]-tag[st]]+=ts[st][e[cha(i)]];
					tt[st][e[cha(i)]]=0;
					ts[st][e[cha(i)]]=0;
				}
			tmax[st]=0;
			for(int i=tl[st];i<=tr[st];i++)
				tmax[st]=max(tmax[st],e[cha(i)]);
		}
		if(tag[ed])
		{
			for(int i=tl[ed];i<=tr[ed];i++)
				if(e[cha(i)]>tag[ed])
				{
					if(ts[ed][e[cha(i)]-tag[ed]])
					{
						fa[cha(i)]=fa[tt[ed][e[cha(i)]-tag[ed]]];
						e[i]=0;
					}
					else
					{
						tt[ed][e[cha(i)]-tag[ed]]=fa[cha(i)];
						e[i]-=tag[ed];
					}
					ts[ed][e[cha(i)]-tag[ed]]+=ts[ed][e[cha(i)]];
					tt[ed][e[cha(i)]]=0;
					ts[ed][e[cha(i)]]=0;
				}
			tmax[ed]=0;
			for(int i=tl[ed];i<=tr[ed];i++)
				tmax[ed]=max(tmax[ed],e[cha(i)]);
		}
		for(int i=l;i<=tr[st];i++)//左 
			if(e[cha(i)]==x)
				s++;
		for(int i=tl[ed];i<=r;i++)//右 
			if(e[cha(i)]==x)
				s++;
		for(int i=st+1;i<=ed-1;i++)//整体
		{
			if(tmax[i]-tag[i]<x)
				continue;
			s+=ts[i][x+tag[i]];
		}
	}
	return s;
}
int p,l,r,x,ans;
int main()
{
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	q=sqrt(n);
	build(1,q);
	while(m--)
	{
		p=read(),l=read(),r=read(),x=read();
		if(p==1)
			change(l,r,x);
		else
		{
			ans=ask(l,r,x);
			write(ans);
			putchar('\n');
		}
	}
	return 0;
}

WA了

2024/1/24 17:23
加载中...