Wa on #10,求助
查看原帖
Wa on #10,求助
178865
小林伊吕波楼主2021/11/27 21:44
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int block=970;
int n,m,cnt,opt[500009],ll[500009],rr[500009],sl[1550],sr[1550],tag[1550],xx[500009],a[1000009];
int root[100009],num[100009],ans[500009],father[1000009],maxn[1550],val[1000009];
inline int Readint()
{
	char ch;
	int i=0,f=1;
	for(ch=getchar();(!isdigit(ch))&&ch!='-';ch=getchar());
	if(ch=='-')
	{
		ch=getchar();
		f=-1;
	}
	for(;isdigit(ch);ch=getchar()) i=(i<<1)+(i<<3)+(ch-'0');
	return i*f;
}
inline int getfather(int x)
{
	if(x==father[x]) return x;
	else {
		father[x]=getfather(father[x]);
		return father[x];
	}
}
inline void rebuild(int p)
{
	for(int j=sl[p];j<=sr[p];++j)
		{
			maxn[p]=max(maxn[p],a[j]);
			num[a[j]]++;
			if(root[a[j]]==0)
			{
				root[a[j]]=j;
				val[j]=a[j];
			} 
			father[j]=root[a[j]];
		}
}
inline void make_pieces()
{
	for(int i=1;i<=n;i+=block)
	{
		sl[++cnt]=i;
		sr[cnt]=min(i+block-1,n);
	}
}
inline void pushdown(int p)
{
	for(int i=sl[p];i<=sr[p];++i)
	{
		a[i]=val[getfather(i)];
		root[a[i]]=num[a[i]]=0;
		a[i]-=tag[p];
	}
	tag[p]=0;
	for(int i=sl[p];i<=sr[p];++i) father[i]=0;
}
inline void merge(int p,int q,int w)
{
	if(root[w]) father[root[q]]=root[w];
	else {
		root[w]=root[q];
		val[root[w]]=w;
	}
	num[w]+=num[q];
	root[q]=num[q]=0;
}
inline void make_tag(int p,int x)
{
	if(x*2<=maxn[p]-tag[p])
	{
	for(int i=tag[p]+1;i<=tag[p]+x;++i)if(root[i]) merge(p,i,i+x); 
	tag[p]+=x;
	return;
    }    
    for(int i=maxn[p];i>tag[p]+x;i--) if(root[i]) merge(p,i,i-x);
    maxn[p]=min(maxn[p],tag[p]+x);
}
inline void change(int p,int l,int r,int x)
{
	if(sl[p]<=l&&r<=sr[p])
	{
		pushdown(p);
		for(int i=l;i<=r;++i) if(a[i]>x) a[i]-=x;
		rebuild(p);
		return;
	}
	if(l<=sl[p]&&sr[p]<=r) 
	{
	    make_tag(p,x);
	    return;
	}
	if(sl[p]<=l&&l<=sr[p])
	{
		pushdown(p);
		for(int i=l;i<=sr[p];++i) if(a[i]>x) a[i]-=x;
		rebuild(p);
	}
	if(sl[p]<=r&&r<=sr[p])
	{
		pushdown(p);
		for(int i=sl[p];i<=r;++i) if(a[i]>x) a[i]-=x;
		rebuild(p);
	}
}
inline int query(int p,int l,int r,int x)
{
	int res=0;
	if(sl[p]<=l&&r<=sr[p])
	{
	     for(int i=l;i<=r;++i) 
		 {
		     if(val[getfather(i)]-tag[p]==x) res++;
		 }
	     return res;
	} 
	if(l<=sl[p]&&sr[p]<=r) if(x+tag[p]<500002) return num[x+tag[p]];
	if(sl[p]<=l&&l<=sr[p])
	{
		for(int i=l;i<=sr[p];++i)
		if(val[getfather(i)]-tag[p]==x) res++;
		return res;
	}
    if(sl[p]<=r&&r<=sr[p])
    {
    	for(int i=sl[p];i<=r;++i)
    	if(val[getfather(i)]-tag[p]==x) res++;
    	return res;
    }
}
int main()
{
	n=Readint(),m=Readint();
	for(int i=1;i<=n;++i) {
		a[i]=Readint();
	}
	make_pieces();
	for(int i=1;i<=m;++i) {
		opt[i]=Readint(),ll[i]=Readint(),rr[i]=Readint(),xx[i]=Readint();
	}
	for(int h=1;h<=cnt;++h)
	{
		memset(root,0,sizeof(root));
		memset(num,0,sizeof(num));
		rebuild(h);
		for(int j=1;j<=m;++j)
		{
			if(ll[j]>sr[h]||rr[j]<sl[h]) continue;
			if(opt[j]==1) change(h,ll[j],rr[j],xx[j]);
			if(opt[j]==2) ans[j]+=query(h,ll[j],rr[j],xx[j]);
		}
	}
	for(int i=1;i<=m;++i) if(opt[i]==2) printf("%d\n",ans[i]);
	return 0;
}
2021/11/27 21:44
加载中...