求助分块 TLE 7pts
查看原帖
求助分块 TLE 7pts
252664
Twig_K楼主2023/8/9 08:39

RT,看到其他被卡常数的都是六七十/ll

快读快写好像没什么用,开 O2 更慢了(

想知道自己是不是写了什么很慢的东西。

目前最后一发提交的代码:

#include<bits/stdc++.h>
using namespace std;
const int maxv=1e5+10;
const int maxn=1e6+10;
const int maxm=5e5+10;
const int maxB=1005;

int B;
int n,m;
int res[maxm];
int a[maxn],K,tag;
int L[maxB],R[maxB];
int cnt[maxn],fa[maxn],rt[maxn],rtv[maxn];
struct node{
	int id,op,x,y,v;
}tmp,q[maxm];

int get(int x){ return (x+B-1)/B; }
int fd(int x){ return (x==fa[x])?x:fa[x]=fd(fa[x]); }
void build(int bl)
{
	K=tag=0;
	memset(rt,0,sizeof(rt));
	memset(cnt,0,sizeof(cnt));
	memset(rtv,0,sizeof(rtv));
	for(int i=L[bl];i<=R[bl];i++)
	{
		K=max(K,a[i]);
		if(rt[a[i]]==0) rt[a[i]]=fa[i]=i,rtv[i]=a[i];
		else fa[i]=rt[a[i]];
		cnt[a[i]]++;
	}
}
void update_t(int bl,int v)//整块修改 
{
	if(K<=v) return;//调试
	if(K-tag>2*v){
		for(int i=tag+1;i<=tag+v;i++)
			if(rt[i])
			{
				int nw=i+v;
				cnt[nw]+=cnt[i],cnt[i]=0;
				if(rt[nw]==0) rt[nw]=rt[i],rtv[rt[nw]]=nw;
				else fa[rt[i]]=rt[nw];
				rt[i]=0;
			}
		tag+=v;
	}else{
		for(int i=v+1;i<=K;i++)
		{
			if(rt[i]==0) continue;
			int nw=i-v;
			cnt[nw]+=cnt[i],cnt[i]=0;
			if(rt[nw]==0) rt[nw]=rt[i],rtv[rt[nw]]=nw;
			else fa[rt[i]]=rt[nw];
			rt[i]=0;
		}
	}
}
void update_p(int bl,int l,int r,int v)//块的部分修改 
{
	for(int i=L[bl];i<=R[bl];i++) a[i]=rtv[fd(i)]-tag;
	for(int i=l;i<=r;i++) if(a[i]>v) a[i]-=v;
	build(bl);
}
int query_t(int bl,int v){ return cnt[v+tag]; }
int query_p(int bl,int l,int r,int v)
{
	int ct=0;
	for(int i=l;i<=r;i++) if(rtv[fd(i)]-tag==v) ct++;
	return ct;
}
signed main()
{
	scanf("%d%d",&n,&m);B=sqrt(n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=m;i++) scanf("%d%d%d%d",&q[i].op,&q[i].x,&q[i].y,&q[i].v),q[i].id=i;
	for(int bl=1;bl<=get(n);bl++) L[bl]=(bl-1)*B+1,R[bl]=bl*B;
	R[get(n)]=n;
	for(int bl=1;bl<=get(n);bl++)
	{
		build(bl);
		for(int t=1;t<=m;t++)
		{
			if(q[t].x>R[bl]||q[t].y<L[bl]) continue;
			tmp=q[t],tmp.x=max(tmp.x,L[bl]),tmp.y=min(tmp.y,R[bl]);
			if(tmp.op==1){
				if(tmp.x==L[bl]&&tmp.y==R[bl]) update_t(bl,tmp.v);
				else update_p(bl,tmp.x,tmp.y,tmp.v);
			}else{
				if(tmp.x==L[bl]&&tmp.y==R[bl]) res[t]+=query_t(bl,tmp.v);
				else res[t]+=query_p(bl,tmp.x,tmp.y,tmp.v);
			}
		}
	}
	for(int i=1;i<=m;i++) if(q[i].op==2) printf("%d\n",res[i]);
	return 0;
}
2023/8/9 08:39
加载中...