BZOJ 2212线段树的合并
2017-02-11 22:25
316 查看
借鉴(抄)了一下题解……
线段树合并的裸题吧…
线段树合并的裸题吧…
//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 4000050 typedef long long LL; int n,cnt,tree[N],son[N][2],root,Root[N],all,tr[N],s[N][2]; LL ans,ans1,ans2; void build(int &x){ x=++cnt; scanf("%d",&tree[x]); if(tree[x])return; build(son[x][0]),build(son[x][1]); } void dfs(int x){ if(!x)return; printf("x=%d tree[x]=%d\n",x,tree[x]); dfs(son[x][0]),dfs(son[x][1]); } void push_up(int x){tr[x]=tr[s[x][0]]+tr[s[x][1]];} void insert(int &x,int l,int r,int wei){ if(!x)x=++all; if(l==r){tr[x]=1;return;} int mid=(l+r)>>1; if(wei<=mid)insert(s[x][0],l,mid,wei); else insert(s[x][1],mid+1,r,wei); push_up(x); } int merge(int x,int y){ if(!x)return y;if(!y)return x; ans1+=1LL*tr[s[x][1]]*tr[s[y][0]]; ans2+=1LL*tr[s[x][0]]*tr[s[y][1]]; s[x][0]=merge(s[x][0],s[y][0]); s[x][1]=merge(s[x][1],s[y][1]); push_up(x);return x; } void solve(int x){ if(tree[x])return; solve(son[x][0]),solve(son[x][1]); ans1=ans2=0; Root[x]=merge(Root[son[x][0]],Root[son[x][1]]); ans+=min(ans1,ans2); } int main(){ scanf("%d",&n); build(root); for(int i=1;i<=cnt;i++)if(tree[i])insert(Root[i],1,n,tree[i]); solve(root); printf("%lld\n",ans); }
相关文章推荐
- BZOJ.2212.[POI2011]Tree Rotations(线段树合并)
- bzoj 2212(线段树合并)
- BZOJ 2212线段树的合并
- [BZOJ3702][BZOJ2212]-线段树合并
- BZOJ 2212 [Poi2011]Tree Rotations(线段树合并)
- [BZOJ2212][Poi2011]Tree Rotations(线段树合并)
- BZOJ 2212 [Poi 2011] 线段树合并 解题报告
- 【bzoj 2212】Tree Rotations(线段树合并)
- BZOJ 2212 线段树启发式合并
- BZOJ 2212 & POI 18 Tree Rotations(线段树合并)
- BZOJ 2212 [Poi2011]Tree Rotations 线段树合并
- bzoj 2212 [Poi2011]Tree Rotations(线段树合并)
- Bzoj2212:[Poi2011]Tree Rotations:线段树的合并
- BZOJ 2212: [Poi2011]Tree Rotations 线段树合并
- [BZOJ2212][POI2011]Tree Rotations(线段树合并)
- BZOJ_2212_[Poi2011]Tree Rotations_线段树合并
- BZOJ2212 POI2011Tree Rotations(线段树合并)
- 神奇的操作——线段树合并(例题: BZOJ2212)
- BZOJ2212 [Poi2011]Tree Rotations 【线段树合并】
- [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】