社区讨论

谁能帮我分析一下时间复杂度

P4344[SHOI2015] 脑洞治疗仪参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@m5te2on0
此快照首次捕获于
2025/01/12 17:04
去年
此快照最后确认于
2025/01/12 21:22
去年
查看原帖
A了,但时间复杂度不会分析。哪个好心人帮我分析一下,谢谢。
CPP
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
   int x=0,f=1;char ch=getchar();
   while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
   while (ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
   return x*f;
}
void write(int x)
{
   if(x<0)putchar('-'),x=-x;
   if(x<10)putchar(x+'0');
   else write(x/10),putchar(x%10+'0');
}
const int N=2e6;
const int mod=1e9+7;
struct node{
	int l,r,lmax,rmax,maxn,tag,sum,nsum;
	node(){
		lmax=rmax=maxn=sum=nsum=0;
		tag=-1;
	}
}tree[N];
void push_up(int p){
	tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
	tree[p].nsum=tree[p<<1|1].nsum+tree[p<<1].nsum;
	tree[p].maxn=max(tree[p<<1].maxn,max(tree[p<<1|1].maxn,tree[p<<1].rmax+tree[p<<1|1].lmax));
	tree[p].lmax=tree[p<<1].lmax+(tree[p<<1].lmax==tree[p<<1].r-tree[p<<1].l+1?tree[p<<1|1].lmax:0);
	tree[p].rmax=tree[p<<1|1].rmax+(tree[p<<1|1].rmax==tree[p<<1|1].r-tree[p<<1|1].l+1?tree[p<<1].rmax:0);
	return;
}
void build(int p,int l,int r){
	tree[p].l=l;
	tree[p].r=r;
	if(l==r){
		tree[p].nsum=1;
		return;
	}
	int mid=l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	push_up(p);
	return; 
}

void pushdown(int p){
	if(tree[p].tag<0)return;
	if(tree[p].tag){
		tree[p<<1].sum=tree[p<<1|1].sum=tree[p<<1].lmax=tree[p<<1].rmax=tree[p<<1|1].lmax=tree[p<<1|1].rmax=tree[p<<1].maxn=tree[p<<1|1].maxn=0;
		tree[p<<1].nsum=tree[p<<1].r-tree[p<<1].l+1;
		tree[p<<1|1].nsum=tree[p<<1|1].r-tree[p<<1|1].l+1;
		tree[p<<1].tag=tree[p<<1|1].tag=1;
	}
	else{
		tree[p<<1].maxn=tree[p<<1].lmax=tree[p<<1].rmax=tree[p<<1].sum=tree[p<<1].r-tree[p<<1].l+1;
		tree[p<<1|1].maxn=tree[p<<1|1].lmax=tree[p<<1|1].rmax=tree[p<<1|1].sum=tree[p<<1|1].r-tree[p<<1|1].l+1;
		tree[p<<1].nsum=tree[p<<1|1].nsum=0;
		tree[p<<1].tag=tree[p<<1|1].tag=0;
	}
	tree[p].tag=-1;
	return;
}
void update(int p,int l,int r,bool fl){
	if(tree[p].l>=l&&tree[p].r<=r){
		if(fl)tree[p].maxn=tree[p].lmax=tree[p].rmax=tree[p].sum=0,tree[p].tag=1,tree[p].nsum=tree[p].r-tree[p].l+1;
		else tree[p].maxn=tree[p].lmax=tree[p].rmax=tree[p].sum=tree[p].r-tree[p].l+1,tree[p].nsum=tree[p].tag=0;
		return;
	}
	pushdown(p);
	int mid=tree[p].l+tree[p].r>>1;
	if(l<=mid)update(p<<1,l,r,fl);
	if(r>mid)update(p<<1|1,l,r,fl);
	push_up(p);
	return; 
}
node qry(int p,int l,int r){
	if(tree[p].l>=l&&tree[p].r<=r)return tree[p];
	node a,b,ret;
	bool fl=0;
	pushdown(p);
	int mid=tree[p].l+tree[p].r>>1;
	if(l<=mid)a=qry(p<<1,l,r),fl =1,ret=a;
	if(r>mid){
		b=qry(p<<1|1,l,r);
		if(fl){
			ret.nsum=a.nsum+b.nsum;
			ret.sum=a.sum+b.sum;
			ret.lmax=a.lmax+(a.lmax==a.r-a.l+1?b.lmax:0);
			ret.rmax=b.rmax+(b.rmax==b.r-b.l+1?a.rmax:0);
			ret.maxn=max(a.maxn,max(b.maxn,a.rmax+b.lmax));
		}
		else ret=b;
	}
	return ret;
}
void up(int p,int l,int r,int k){
	if(tree[p].l>=l&&tree[p].r<=r&&tree[p].sum<=k){
		tree[p].maxn=tree[p].lmax=tree[p].rmax=tree[p].sum=0,tree[p].tag=1,tree[p].nsum=tree[p].r-tree[p].l+1;
		return ;
	}
	pushdown(p);
	int mid=tree[p].l+tree[p].r>>1;
	int rt=0;
	if(l<=mid)rt=qry(1,max(l,tree[p].l),mid).sum,up(p<<1,l,r,min(k,rt));
	if((k-rt>0||l>mid)&&r>mid)up(p<<1|1,l,r,l<=mid?k-rt:k);
	push_up(p);
	return;
}
int n,m;
signed main(){
	n=read(),m=read(); 
  	build(1,1,n);
	while(m--){
  		int op=read(),x=read(),y=read();
		  if(op==0)update(1,x,y,0);
		  if(op==1){ 
		  	int xx=read(),yy=read();
		  	int kl=qry(1,x,y).nsum; 
		  	update(1,x,y,0);
		  	if(kl==0)continue; 
		  	up(1,xx,yy,kl);
		  }
		  if(op==2)cout<<qry(1,x,y).maxn<<"\n"; 
	  }
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...