萌新求教卡常。。
查看原帖
萌新求教卡常。。
62308
Mr_Wu楼主2022/4/12 15:16

我写的是 这个做法

但它 TLE 了,分数在 60 左右浮动。

能不能帮我看看怎么卡常。。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
template<typename T> void chkmax(T& x,T y){if(y>x)x=y;}
template<typename T> void chkmin(T& x,T y){if(y<x)x=y;}
const int MAXN=3e5+5;

namespace IO{
	char ibuf[1<<20],*ip1=0,*ip2=0;
	char gc(){if(ip1==ip2)ip1=ibuf,ip2=ibuf+fread(ibuf,1,1<<20,stdin);return ip1==ip2?EOF:*ip1++;}
	char obuf[1<<20],*op1=obuf,*op2=obuf+(1<<20);
	void flush(){fwrite(obuf,1,op1-obuf,stdout);}
	void pc(char c){*op1++=c;if(op1==op2)flush(),op1=obuf;}
	struct ioo{ioo(){}~ioo(){flush();}}ioo;
};
using namespace IO;
int read(){
	int ret=0,t=1;char c=gc();
	while((c<'0'||c>'9')&&c!='-')c=gc();if(c=='-')t=-1,c=gc();
	while(c>='0'&&c<='9')ret=ret*10+c-'0',c=gc();return ret*t;
}
void print(ull x){
	if(x==0){pc('0');return;}if(x<0)pc('-'),x=-1;
	static char buf[100],bufl;while(x)buf[++bufl]=x%10,x/=10;
	while(bufl)pc('0'+buf[bufl--]);
}

inline ull qwq(int x){return 1ull*x*(x+1)/2;}

int N,M,Blo,a[MAXN],A[MAXN];
struct query{int op,x,y,z;}q[MAXN];int cl[MAXN];ull ans[MAXN];
int lb[MAXN],rb[MAXN],blo[MAXN];

struct dsu{
	int fa[MAXN],siz[MAXN];
	void init(int l,int r){for(int i=l;i<=r;++i)fa[i]=i,siz[i]=1;}
	int get(int x){if(fa[x]!=x)fa[x]=get(fa[x]);return fa[x];}
	void merge(int x,int y){
		x=get(x),y=get(y);if(x==y)return;
		if(siz[x]>siz[y])swap(x,y);
		fa[x]=y,siz[y]+=siz[x];
	}
}dsu;

int sorted[MAXN],rk[MAXN];
bool cmp(int i,int j){return a[i]<a[j];}
int llen[MAXN],rlen[MAXN],sum[MAXN];

struct ds{
	int buc[MAXN],val[MAXN],valb[MAXN];
	void ins(int pos,int k){
		buc[pos]+=k;int fir=0;
		for(int i=lb[blo[pos]];i<=rb[blo[pos]];++i){if(buc[i])fir=i;val[i]=fir;}
		if(!fir)fir=valb[blo[pos]];
		for(int i=blo[pos]+1;i<=blo[N];++i){
			valb[i]=fir;
			if(val[rb[i]])break;
		}
	}
	int qry(int pos){return val[pos]?val[pos]:valb[blo[pos]];}
	void clear(){for(int i=1;i<=N;++i)buc[i]=val[i]=0;for(int i=1;i<=blo[N];++i)valb[i]=0;}
}ds;

void rebuild(int cur){
	static bool buc[MAXN];
	dsu.init(lb[cur],rb[cur]);
	int cursum=0;
	for(int j=lb[cur];j<=rb[cur];++j){
		int id=sorted[j];
		if(buc[id-1])cursum-=dsu.get(lb[cur])!=dsu.get(id-1)?qwq(dsu.siz[dsu.get(id-1)]):0,dsu.merge(id-1,id);
		if(buc[id+1])cursum-=dsu.get(rb[cur])!=dsu.get(id+1)?qwq(dsu.siz[dsu.get(id+1)]):0,dsu.merge(id,id+1);
		buc[id]=1,cursum+=dsu.get(lb[cur])!=dsu.get(id)&&dsu.get(rb[cur])!=dsu.get(id)?qwq(dsu.siz[dsu.get(id)]):0;
		llen[j]=buc[lb[cur]]?dsu.siz[dsu.get(lb[cur])]:0,rlen[j]=buc[rb[cur]]?dsu.siz[dsu.get(rb[cur])]:0,sum[j]=cursum;
	}
	for(int j=lb[cur];j<=rb[cur];++j)buc[j]=0;
}

int main(){
	N=read(),M=read(),Blo=sqrt(N);
	for(int i=1;i<=N;++i)a[i]=read(),A[i]=a[i];
	for(int i=1;i<=N;++i)blo[i]=(i-1)/Blo+1;
	for(int i=1;i<=blo[N];++i)lb[i]=(i-1)*Blo+1,rb[i]=min(N,i*Blo);
	for(int i=1;i<=M;++i){
		q[i].op=read();
		if(q[i].op==1)q[i].x=read(),q[i].y=read();
		else q[i].x=read(),q[i].y=read(),q[i].z=read();
	}
	for(int cur=1;cur<=blo[N];++cur){
		for(int i=1;i<=N;++i)a[i]=A[i],rk[i]=0;
		for(int i=lb[cur];i<=rb[cur];++i)sorted[i]=i;
		sort(sorted+lb[cur],sorted+rb[cur]+1,cmp),rebuild(cur);
		ds.clear();
		for(int i=lb[cur];i<=rb[cur];++i)rk[a[sorted[i]]]=i,ds.ins(a[i],1);
		for(int i=1;i<=M;++i){
			if(q[i].op==1){
				if(lb[cur]<=q[i].x&&q[i].x<=rb[cur]){
					for(int j=lb[cur];j<=rb[cur];++j)rk[a[j]]=0;
					int j;for(j=lb[cur];j<=rb[cur];++j)if(sorted[j]==q[i].x)break;
					for(;j<rb[cur];++j)sorted[j]=sorted[j+1];sorted[rb[cur]]=0;
					ds.ins(a[q[i].x],-1),a[q[i].x]=q[i].y,ds.ins(a[q[i].x],1);
					for(j=lb[cur];j<rb[cur];++j)if(a[sorted[j]]>=q[i].y)break;
					for(int k=rb[cur];k>j;--k)sorted[k]=sorted[k-1];sorted[j]=q[i].x;
					for(int j=lb[cur];j<=rb[cur];++j)rk[a[sorted[j]]]=j;
					rebuild(cur);
				}
			}else{
				if(q[i].x<=lb[cur]&&rb[cur]<=q[i].y){
					int po=rk[ds.qry(q[i].z)];
					if(llen[po]==rb[cur]-lb[cur]+1)cl[i]+=llen[po];
					else{
						cl[i]+=llen[po],ans[i]+=qwq(cl[i]),cl[i]=0;
						ans[i]+=sum[po],cl[i]=rlen[po];
					}
				}else{
					int ll=1,rr=0;
					if(lb[cur]<=q[i].x&&q[i].y<=rb[cur])ll=q[i].x,rr=q[i].y;
					else if(lb[cur]<q[i].x&&q[i].x<=rb[cur])ll=q[i].x,rr=rb[cur];
					else if(lb[cur]<=q[i].y&&q[i].y<rb[cur])ll=lb[cur],rr=q[i].y;
					for(int j=ll;j<=rr;++j){
						if(a[j]<=q[i].z)++cl[i];
						else ans[i]+=qwq(cl[i]),cl[i]=0;
					}
				}
			}
		}
	}
	for(int i=1;i<=M;++i)if(q[i].op==2){
		ans[i]+=qwq(cl[i]);
		print(ans[i]),pc('\n');
	}
	return 0;
}
2022/4/12 15:16
加载中...