60分求调
查看原帖
60分求调
473635
Nobelium_255楼主2023/7/18 10:03

提交记录

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
template<typename T>
void read(T& x){
	char c=getchar();bool a=0;x=0;
	while(!isdigit(c)){
		if(c=='-') a^=1;
		c=getchar();
	}
	while(isdigit(c)){
		x=x*10+c-'0';
		c=getchar();
	}
	if(a) x*=-1;
	return;
}
template<typename T,typename ...Args>
void read(T& x,Args&... args){
	read(x),read(args...);
	return; 
}

#define SQRT ((int)325)
#define LOG ((int)40)
#define N ((int)1e5)
//#define DBG

int n,m,tot;
/*
n,m:如题
tot:节点长度不同的序列数 
*/
int p[N+10];
struct Sequence{
	int cnt,tot;
	/*
	cnt:序列中节点数 
	tot:序列中块数 
	*/
	struct Node{
		int l,r,v;
		bool operator<(const Node &b)const{
			return v<b.v;
		}
	}ss[N+10];
	struct Block{
		int l,r,ll,rr,lazy;
	}pp[SQRT];
	int value(int x,int y){
		return ss[x].v+(ss[x].r-ss[x].l+1)*pp[y].lazy;
	}
	void add_block(int i,int l,int r,int k){
		if(l<=pp[i].ll&&pp[i].rr<=r) pp[i].lazy+=k;
		else{
			for(int j=pp[i].l;j<=pp[i].r;j++){
				if(r<ss[j].l||ss[j].r<l) continue;
				ss[j].v+=k*(min(ss[j].r,r)-max(ss[j].l,l)+1);
			}
			sort(ss+pp[i].l,ss+pp[i].r+1);
		}
		return;
	}
	int query_block(int i,int l,int r,int k){
		if(l<=pp[i].ll&&pp[i].rr<=r){
			int L=pp[i].l,R=pp[i].r,mid;
			while(L<R){
				mid=(L+R+1)>>1;
				if(value(mid,i)>k){
					R=mid-1;
				}else{
					L=mid;
				}
			}
			if(value(L,i)>k) return 0;
			return L-pp[i].l+1;
		}else{
			int re=0;
			for(int j=pp[i].l;j<=pp[i].r;j++){
				if(l<=ss[j].l&&ss[j].r<=r&&value(j,i)<=k){
					re++;
				}
			}
			return re;
		}
	}
	void init(){
		int len=sqrt(cnt),tmp=1;
		while(tmp+len-1<=cnt){
			pp[++tot]={tmp,tmp+len-1,ss[tmp].l,ss[tmp+len-1].r,0};
			tmp+=len;
		}
		if(tmp<=cnt){
			pp[++tot]={tmp,cnt,ss[tmp].l,ss[cnt].r,0};
		}
		return;
	}
	void add(int l,int r,int k){
		int L=1,R=tot,mid;
		while(L<R){
			mid=(L+R+1)>>1;
			if(pp[mid].ll>l){
				R=mid-1;
			}else{
				L=mid;
			}
		}
		for(int i=L;i<=tot&&pp[i].ll<=r;i++){
			add_block(i,l,r,k);
		}
		return;
	}
	int query(int l,int r,int k){
		int L=1,R=tot,mid;
		while(L<R){
			mid=(L+R+1)>>1;
			if(pp[mid].ll>l){
				R=mid-1;
			}else{
				L=mid;
			}
		}
		int re=0;
		for(int i=L;i<=tot&&pp[i].ll<=r;i++){
			re+=query_block(i,l,r,k);
		}
		return re;
	}
}s[LOG];

#define ls (i<<1)
#define rs (i<<1|1)
void build(int i,int L,int R){
	int len=R-L+1;
	if(!p[len]) p[len]=++tot;
	s[p[len]].ss[++s[p[len]].cnt]=(Sequence::Node){L,R,0};
	if(L==R) return;
	int mid=(L+R)>>1;
	build(ls,L,mid);
	build(rs,mid+1,R);
	return;
}
#undef ls
#undef rs

void op1(int l,int r,int k){
	for(int i=1;i<=tot;i++){
		s[i].add(l,r,k);
	}
	return;
}

void op2(int l,int r,int k){
	int ans=0;
	for(int i=1;i<=tot;i++){
		ans+=s[i].query(l,r,k);
	}
	printf("%d\n",ans);
	return;
}

void init(){
	for(int i=1;i<=tot;i++){
		s[i].init();
	}
	return;
}

#ifdef DBG
void show(){
	printf("tot=%d\n",tot);
	for(int i=1;i<=tot;i++){
		printf("s[%d]:tot=%d,cnt=%d\n",i,s[i].tot,s[i].cnt);
		for(int j=1;j<=s[i].tot;j++){
			printf("-pp[%d]={[%d,%d],[%d,%d],lazy=%d}:\n",j,s[i].pp[j].l,s[i].pp[j].r,s[i].pp[j].ll,s[i].pp[j].rr,s[i].pp[j].lazy);
			for(int k=s[i].pp[j].l;k<=s[i].pp[j].r;k++){
				printf("--ss[%d]={[%d,%d],%d}\n",k,s[i].ss[k].l, s[i].ss[k].r, s[i].ss[k].v);
			}
		}
		printf("\n");
	}
	return;
}
#endif

int main(){
	read(n,m);
	build(1,1,n);
	init();
	#ifdef DBG
	show();
	#endif
	for(int i=1,op,l,r,k;i<=m;i++){
		read(op,l,r,k);
		if(op==1){
			op1(l,r,k);
		}else{
			op2(l,r,k);
		}
		#ifdef DBG
		show();
		#endif
	}
	return 0;
} 
2023/7/18 10:03
加载中...