hdu 6183 线段树的空间优化
生活随笔
收集整理的這篇文章主要介紹了
hdu 6183 线段树的空间优化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
一個空的坐標系,有④種操作:①1 x y c表示在(x, y)點染上顏色c;②2 X y1 y2表示查詢在(1, y1)到(X, y2)范圍內有多少種不同的顏色:
③0表示清屏;④3表示程序退出(0<=x, y<=1000000, 0<=c<=50)
?
思路:開五十個線段樹(一種顏色一個),以y為下表,保存min x,(因為查詢x固定1---X)然后暴力查詢50個就好了
但是顯然碰到了一個問題,1e6 開50個線段樹顯然不現實。。所以需要空間優化一下。。。這里我們考慮動態來開辟線段樹,有效的節點進行分配,無效則不分配。。。提問,這樣空間為什么是合理的呢?其實因為一個add 最多開logn個節點,單組只有1.5e5次查詢,顯然,最多也就只開了qlogn個。那么這樣空間復雜度就是合理的了。。具體動態開辟的實現也非常簡單,類比trie,見代碼。
?
代碼:
?
#include<bits/stdc++.h> using namespace std; #define MEM(x,y) memset(x,y,sizeof(x)); const int maxn=3e6+10; int root[55]; int L[maxn],R[maxn],tot,sum[maxn]; void update(int &rt,int idx,int val,int l,int r){if(rt==-1) rt=tot++;sum[rt]=min(val,sum[rt]);if(l==r) return;int mid=(l+r)/2;if(idx<=mid) update(L[rt],idx,val,l,mid);else update(R[rt],idx,val,mid+1,r);return; } int query(int rt,int l,int r,int ll,int rr){int ret=1e9;if(rt==-1) return ret;if(ll==l&&rr==r) return sum[rt];int mid=(ll+rr)/2;if(r<=mid) ret=query(L[rt],l,r,ll,mid);else if(l>mid) ret=query(R[rt],l,r,mid+1,rr);else ret=min(query(L[rt],l,mid,ll,mid),query(R[rt],mid+1,r,mid+1,rr));return ret; } int main(){int t,n,op,x,y,y1,y2,c,ret;while(scanf("%d",&op)){if(op==0){MEM(L,-1);MEM(R,-1);for(int i=0;i<maxn;++i) sum[i]=1e9;tot=52;}else if(op==1){scanf("%d%d%d",&x,&y,&c);update(c,y,x,1,1e6);}else if(op==2){scanf("%d%d%d",&x,&y1,&y2);ret=0;for(int i=0;i<=50;++i)ret+=(query(i,y1,y2,1,1e6)<=x);printf("%d\n",ret);}else if(op==3) break;} }?
轉載于:https://www.cnblogs.com/zhangxianlong/p/10672487.html
總結
以上是生活随笔為你收集整理的hdu 6183 线段树的空间优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做梦梦到好多蛇死了是什么意思
- 下一篇: iOS使用自定义字体(添加字体包)