mxqz
查看原帖
mxqz
409372
Alice_and_Bob楼主2023/7/16 21:29

wa了1-4,11-14

44pts

求调

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
#include<queue>
#include<bits/stdc++.h>
#define ll long long
//#define int ll
#define register re
using namespace std;
const int N=1e6+10,M=1e6+10,A=1e5+1,B=1e3+1;
inline int read(){
    int d=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){d=(d<<1)+(d<<3)+(ch^48);ch=getchar();}
    return d*f;
}
inline int max(const int &x,const int &y){return x>y?x:y;}
inline int min(const int &x,const int &y){return x<y?x:y;}
int fa[N],rt[N],val[N],sz[N];
inline void merge(int x,int y){
	if(rt[y]) fa[rt[x]]=rt[y],val[rt[x]]=0;
	else rt[y]=rt[x],val[rt[y]]=y;
	sz[y]+=sz[x],rt[x]=sz[x]=0;
}
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int n,m,a[N],ans[M];
struct block{int l,r,mx,tag;}b[N/B+10];
struct Qry{int op,ql,qr,x;}q[M];
inline void build(int t){
	for(int i=b[t].l;i<=b[t].r;i++){
		if(!rt[a[i]]) b[t].mx=max(b[t].mx,a[i]),rt[a[i]]=i,fa[i]=i,val[i]=a[i];
		else fa[i]=rt[a[i]],val[i]=0;
		sz[a[i]]++;
	}
}
inline void re(int t,int l,int r,int x){
	for(int i=b[t].l;i<=b[t].r;i++){int u=val[find(i)];a[i]=u-b[t].tag,rt[u]=0,sz[u]=0;}
	for(int i=l;i<=r;i++) if(a[i]>x) a[i]-=x;b[t].mx=b[t].tag=0;
	for(int i=b[t].l;i<=b[t].r;i++){
		if(!rt[a[i]]) b[t].mx=max(b[t].mx,a[i]),rt[a[i]]=i,fa[i]=i,val[i]=a[i];
		else fa[i]=rt[a[i]],val[i]=0;
		sz[a[i]]++;
	}
}
inline void upd(int t,int l,int r,int x){
	if(l!=b[t].l||r!=b[t].r) return re(t,l,r,x),void();
	int mx=b[t].mx-b[t].tag;
	if(mx<=2*x){
		for(int i=1;i<=mx-x;i++) if(rt[i+x]) merge(i+x,i);
		b[t].mx=min(b[t].mx,x+b[t].tag);
	}
	else {for(int i=1;i<=x;i++) if(rt[i]) merge(i,i+x);b[t].tag+=x;}
}
inline int qy(int t,int l,int r,int x){
	int res=0;
	for(int i=l;i<=r;i++) if(val[find(i)]-b[t].tag==x) res++;
	return res;
}
inline int qry(int t,int l,int r,int x){
	if(l!=b[t].l||r!=b[t].r) return qy(t,l,r,x);
	return sz[x+b[t].tag];
}
signed main(){
	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].ql=read(),q[i].qr=read(),q[i].x=read();
	for(int i=1;i<=(n+B-1)/B;i++) b[i].l=(i-1)*B+1,b[i].r=min(n,i*B);
	for(int i=1;i<=(n+B-1)/B;i++) for(int j=b[i].l;j<=b[i].r;j++) b[i].mx=max(b[i].mx,a[j]);
	for(int t=1;t<=(n+B-1)/B;t++){
		memset(rt,0,sizeof(rt));memset(sz,0,sizeof(sz));
		memset(fa,0,sizeof(fa));memset(val,0,sizeof(val));
		// for(int i=0;i<=A;i++) rt[i]=0;memset(sz,0,sizeof(sz));
		build(t);
		for(int i=1;i<=m;i++){
			if(q[i].op==1){
				if(q[i].x==0) continue;
				if(b[t].mx-b[t].tag<=q[i].x) continue;
				int L=max(b[t].l,q[i].ql),R=min(b[t].r,q[i].qr);
				if(L>R) continue;
				upd(t,L,R,q[i].x);
			}else{
				if(b[t].mx-b[t].tag<q[i].x) continue;
				int L=max(b[t].l,q[i].ql),R=min(b[t].r,q[i].qr);
				if(L>R) continue;
				ans[i]+=qry(t,L,R,q[i].x);
			}
		}
	}
	for(int i=1;i<=m;i++) if(q[i].op==2) printf("%d\n",ans[i]);
	return 0;
}
2023/7/16 21:29
加载中...