HDU - 6183 動態開點線段樹 || 令人絕望的線段樹


一看C才[0,50],肯定要開51棵線段樹維護y區間的最小x值啦
是男人就上51棵..等等空間爆幾倍了
動態開點!51棵線段樹用全局節點變量控制,有點像主席樹
清空工作很簡單,把51個樹根清掉然后回收節點(tot=0)就行了
然而!真不知道那些內部數據是有多惡心的
MLE × 4
RTE × 4
最后在query那里強行截斷9900ms+水過.....
看了下空間占用才8000k左右hhh
現場賽能做出來得鍵盤開光吧

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define clr(a,b) memset(a,b,sizeof a)
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int maxn = 2e6+5e5+11;
const int oo = 0x3f3f3f3f;
int T[70];
struct ST{
	int L[maxn<<2],R[maxn<<2],minx[maxn<<2];
	int tot;
	void init(){
		clr(T,0);
		tot=0;
		L[0]=R[0]=0;
		minx[0]=oo;
	}
	void pu(int o){
		minx[o]=min(minx[L[o]],minx[R[o]]); 
	}
	void update(int &o,int l,int r,int y,int x){
		if(!o){
			o=++tot;
			L[o]=R[o]=0;
			minx[o]=x;
		}
		if(l==r){
			minx[o]=min(minx[o],x);
			return ;
		}
		int m=l+r>>1;
		if(y<=m) update(L[o],l,m,y,x);
		else update(R[o],m+1,r,y,x);
		pu(o);
	}
	int query(int &o,int l,int r,int LL,int RR){
		if(!o){
		    return oo; //很重要!!!
		}
		if(LL<=l&&r<=RR){
			return minx[o];
		}
		int m=l+r>>1;
		int ans=oo;
		if(LL<=m) ans=min(ans,query(L[o],l,m,LL,RR));
		if(RR>m) ans=min(ans,query(R[o],m+1,r,LL,RR));
		return ans;
	}
}st; 
const int n = 1e6;
int main(){
	int op,x,y,yy1,yy2,c;
	st.init();
	while(scanf("%d",&op)!=EOF){
		if(op==3)break;
		else if(op==0) st.init();
		else if(op==1){
			scanf("%d%d%d",&x,&y,&c);
			st.update(T[c],1,n,y,x);
		}
		else if(op==2){
			scanf("%d%d%d",&x,&yy1,&yy2);
			int ans=0,tmp;
			rep(i,0,50){
				tmp=st.query(T[i],1,n,yy1,yy2);
				if(tmp<=x) ans++;
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM