7pts求卡常
查看原帖
7pts求卡常
704275
无名之雾楼主2024/6/29 19:21

感觉不应该这么慢吧?

#include<bits/stdc++.h>
using namespace std;
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;
}
inline void out(int x){
    if(x==0){putchar('0');return;}
	int len=0,k1=x,c[10005];
	if(k1<0)k1=-k1,putchar('-');
	while(k1)c[len++]=k1%10+'0',k1/=10;
	while(len--)putchar(c[len]);
}
const int N=5e5+5,M=1e3+5,NM=1e6+10;
int ans[N],a[NM],st[M],ed[M],pos[NM],cnt[NM],s[NM],rt[NM],rtv[NM];
int K,tag;
struct node{
	int op,x,y,v;
}q[N];
int find(int x){
	if(x!=s[x])s[x]=find(s[x]);
	return s[x]; 
}
inline void build(int x){
	K=tag=0;
	memset(rt,0,sizeof(rt));
	memset(cnt,0,sizeof(cnt));
	memset(rtv,0,sizeof(rtv));
	for(int i=st[x];i<=ed[x];i++){
		K=max(K,a[i]);
		if(!rt[a[i]])rt[a[i]]=s[i]=i,rtv[i]=a[i];
		else s[i]=rt[a[i]];
		cnt[a[i]]++;
	}
}
inline void upd1(int x){
	if(K-tag>2*x){
		for(int i=tag+1;i<=tag+x;i++){
			if(rt[i]){
				int nw=i+x;
				cnt[nw]+=cnt[i],cnt[i]=0;
				if(rt[nw]==0)rt[nw]=rt[i],rtv[rt[nw]]=nw;
				else s[rt[i]]=rt[nw];
				rt[i]=0;
			}
		}
		tag+=x;
	}
	else{
		for(int i=x+1;i<=K;i++){
			if(rt[i]==0)continue;
			int nw=i-x;
			cnt[nw]+=cnt[i],cnt[i]=0;
			if(rt[nw]==0)rt[nw]=rt[i],rtv[rt[nw]]=nw;
			else s[rt[i]]=rt[nw];
			rt[i]=0;
		}
	}
}
inline void upd2(int x,int l,int r,int v){
	for(int i=st[x];i<=ed[x];i++)a[i]=rtv[find(i)]-tag;
	for(int i=l;i<=r;i++){
		if(a[i]>v)a[i]-=v;
	}
	build(x);
}
inline int query1(int x){ 
	return cnt[x+tag]; 
}
inline int query2(int l,int r,int x){
	int cnt=0;
	for(int i=l;i<=r;i++){
		if(rtv[find(i)]-tag==x)cnt++;
	}
	return cnt;
}
signed main(){
	int n=read(),m=read();
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=m;i++)q[i].op=read(),q[i].x=read(),q[i].y=read(),q[i].v=read();
	int block=sqrt(n),t=n/block;
	for(int i=1;i<=t;i++){
		st[i]=(i-1)*block+1;
		ed[i]=i*block; 
	}
	ed[t]=n;
	for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1;
	for(int i=1;i<=t;i++){
		build(i);
		for(int j=1;j<=m;j++){
			if(q[j].x>ed[i]||q[j].y<st[i])continue;
			int l=max(q[j].x,st[i]),r=min(q[j].y,ed[i]),v=q[j].v,op=q[j].op;
			if(op==1){
				if(l==st[i]&&r==ed[i])upd1(v);
				else upd2(i,l,r,v);
			}
			else{
				if(l==st[i]&&r==ed[i])ans[j]+=query1(v);
				else ans[j]+=query2(l,r,v);
			}
		}
	}
	for(int i=1;i<=m;i++) {
		if(q[i].op==2)out(ans[i]),puts("");
	}
	return 0;
}
2024/6/29 19:21
加载中...