diff --git a/POJ/3667.cpp b/POJ/3667.cpp new file mode 100644 index 0000000..8767cd1 --- /dev/null +++ b/POJ/3667.cpp @@ -0,0 +1,161 @@ +/// General includes +#include +#include +#include + +#include +using namespace std; + +/// 区间赋值更新, 区间合并, 查找左端 +namespace AttributeSumSegmentTree +{ + +const int MAXN = 100100; +const int MAXTREENODE = MAXN << 3; +const int ATTR_BY_DEFAULT=-1;///默认初始化属性 -1 无需操作 0 子树有住户离开 1 子树有住户进入 + +struct node +{ + int lt,rt; + int lsum,rsum,sum; + int attr; +}; + +node tree[MAXTREENODE]; + +void build(int L,int R,int _indexer=1) +{ + tree[_indexer].lt=L; + tree[_indexer].rt=R; + tree[_indexer].attr=ATTR_BY_DEFAULT; + tree[_indexer].lsum=tree[_indexer].rsum=tree[_indexer].sum=R-L+1; + if(L!=R) + { + int mid=(L+R)>>1; + build(L,mid,_indexer<<1); + build(mid+1,R,_indexer<<1|1); + } +} + +void update(int L,int R,int NewAttr,int _indexer=1) +{ + if(L==tree[_indexer].lt&&R==tree[_indexer].rt) + { + tree[_indexer].lsum=tree[_indexer].rsum=tree[_indexer].sum= + NewAttr==1 ? 0 : tree[_indexer].rt-tree[_indexer].lt+1 ; /// Same as R-L+1 + tree[_indexer].attr=NewAttr; + return; + } + + /// Push Down (updated) + if(tree[_indexer].attr!=-1) + { + /// Sync the Attribute to sub-tree + tree[_indexer<<1].attr=tree[_indexer<<1|1].attr=tree[_indexer].attr; + tree[_indexer].attr=-1; + tree[_indexer<<1].rsum=tree[_indexer<<1].lsum=tree[_indexer<<1].sum= tree[_indexer<<1].attr==1 ? 0 : tree[_indexer<<1].rt-tree[_indexer<<1].lt+1; + tree[_indexer<<1|1].rsum=tree[_indexer<<1|1].lsum=tree[_indexer<<1|1].sum= tree[_indexer<<1|1].attr==1 ? 0 : tree[_indexer<<1|1].rt-tree[_indexer<<1|1].lt+1; + } + + int mid=(tree[_indexer].lt+tree[_indexer].rt)>>1; + if(R<=mid) + { + update(L,R,NewAttr,_indexer<<1); + } + else if(L>mid) + { + update(L,R,NewAttr,_indexer<<1|1); + } + else + { + update(L,mid,NewAttr,_indexer<<1); + update(mid+1,R,NewAttr,_indexer<<1|1); + } + + /// Push Up (updated) + tree[_indexer].lsum=tree[_indexer<<1].lsum; /// left & left + tree[_indexer].rsum=tree[_indexer<<1|1].rsum; /// right & right + + if(tree[_indexer<<1].lsum == tree[_indexer<<1].rt-tree[_indexer].lt+1) + { + /// Father.LeftSum == RightSon.LeftSum + LeftSon.LeftSum + tree[_indexer].lsum+=tree[_indexer<<1|1].lsum; + } + + /// Why tree[_indexer].rsum but not tree[_indexer<<1|1].rsum ??? + if(tree[_indexer].rsum==tree[_indexer<<1|1].rt-tree[_indexer<<1|1].lt+1) + { + /// Father.RightSum == LeftSon.RightSum + RightSon.RightSum + tree[_indexer].rsum+=tree[_indexer<<1].rsum; + } + + tree[_indexer].sum=max(max(tree[_indexer<<1].sum,tree[_indexer<<1|1].sum),tree[_indexer<<1].rsum+tree[_indexer<<1|1].lsum); + + +} + +int query(int Val,int _indexer=1) +{ + if(tree[_indexer].lt==tree[_indexer].rt) + { + return tree[_indexer].lt; + } + /// Push Down (updated) + if(tree[_indexer].attr!=-1) + { + /// Sync the Attribute to sub-tree + tree[_indexer<<1].attr=tree[_indexer<<1|1].attr=tree[_indexer].attr; + tree[_indexer].attr=-1; + tree[_indexer<<1].rsum=tree[_indexer<<1].lsum=tree[_indexer<<1].sum= tree[_indexer<<1].attr==1 ? 0 : tree[_indexer<<1].rt-tree[_indexer<<1].lt+1; + tree[_indexer<<1|1].rsum=tree[_indexer<<1|1].lsum=tree[_indexer<<1|1].sum= tree[_indexer<<1|1].attr==1 ? 0 : tree[_indexer<<1|1].rt-tree[_indexer<<1|1].lt+1; + } + int Mid=(tree[_indexer].rt+tree[_indexer].lt)>>1; + /// Left + if(tree[_indexer<<1].sum>=Val) + { + return query(Val,_indexer<<1); + } + /// Both Left and Right + else if(tree[_indexer<<1].rsum+tree[_indexer<<1|1].lsum >= Val) + { + return Mid-tree[_indexer<<1].rsum+1; + } + else /// Right + { + return query(Val,_indexer<<1|1); + } +} + +}/// End of namespace AttributeSumSegmentTree + +int main() +{ + using namespace AttributeSumSegmentTree; + int N,M; + scanf("%d %d",&N,&M); + build(1,N); + while(M--) + { + int op; + scanf("%d",&op); + if(op==1) /// Check in + { + int x; + scanf("%d",&x); + if(tree[1].sum