动态开点线段树求调(玄关)
查看原帖
动态开点线段树求调(玄关)
544310
wuhupai楼主2023/11/13 14:18

rt找了半天没找出来问题

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,cnt=0,ans=0,maxn;
bool vis[1005];
struct node{
	int ls,rs,p,la;
}d[20000005];
void push_up(int p){
	d[p].p=d[d[p].ls].p+d[d[p].rs].p;
}
void push_down(int l,int r,int p,int mid){
	if(d[p].la!=0){
		d[d[p].ls].p=d[p].la*(mid-l+1);
		d[d[p].rs].p=d[p].la*(r-mid);
		d[d[p].ls].la=d[p].la;
		d[d[p].rs].la=d[p].la;
		d[p].la=0;
	}
}
void build(int l,int r,int pos,int p){
	if(l==r) return;
	int mid=(l+r)>>1;
	if(pos<=mid){
		if(d[p].ls==0){
			cnt++;
			d[p].ls=cnt;
		}build(l,mid,pos,d[p].ls);
	}else{
		if(d[p].rs==0){
			cnt++;
			d[p].rs=cnt;
		}build(mid+1,r,pos,d[p].rs);
	}
	push_up(p);
}
void update(int l,int r,int p,int ad,int s,int t){
	if(l>=s&&r<=t){
		d[p].la=ad;
		d[p].p=(r-l+1)*ad;
		return;
	}
	int mid=(l+r)>>1;
	push_down(l,r,p,mid);
	if(s<=mid) update(l,mid,d[p].ls,ad,s,t);
	if(t>mid) update(mid+1,r,d[p].rs,ad,s,t);
	push_up(p);
}
int getsum(int l,int r,int p,int s){
	if(l==s&&r==s){
		return d[p].p;
	}
	int mid=(l+r)>>1,ans=0;
	push_down(l,r,p,mid);
	if(s<=mid) ans+=getsum(l,mid,d[p].ls,s);
	if(s>mid) ans+=getsum(mid+1,r,d[p].rs,s);
	return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		build(1,n,i,1);
	}
	for(int i=1;i<=m;i++){
		cin>>x>>y;
		update(1,n,1,1,x,y);
		//cout<<getsum(1,n,1,x)<<endl;
	}
	for(int i=1;i<=n;i++){
		int g=getsum(1,n,1,i);
		//cout<<g<<endl;
		if(vis[g]==false){
			vis[g]=true;
			ans++;
		}
	}
	cout<<ans<<endl;
	
	return 0;
}

2023/11/13 14:18
加载中...