Hdu 6133 启发式合并
来源:互联网 发布:网络与新媒体是干嘛的 编辑:程序博客网 时间:2024/06/05 08:27
今(yi)天(zhi)被NJU(suoyou)的多校虐得满地找牙。。
第一次写启发式合并。。
大概就是大的子树只更新一次,把小的子树往大的里面抽插(233)。。
然后就可以了。。
唯一的问题是我代码能力十分捉急,写出了n个bug。。
//启发式合并get//NJU很牛逼啊//这个sumofsum树状数组也很套路啊//我TM好菜菜啊#include <bits/stdc++.h>using namespace std;typedef long long ll;int a[105000];int id[105000];int b[105000];ll num[105000];ll sum[105000];int lson[105000];int rson[105000];int n;int cmp(int x, int y){ if(a[x]==a[y])return x<y; return a[x]<a[y];}struct edge{ int to, next;}e[205000];int head[105000];int cnt;int siz[105000];ll ans[105000];ll tmp;ll tot;void init(){ tmp=0; memset(lson, -1, sizeof(lson)); memset(rson, -1, sizeof(rson)); memset(ans, 0, sizeof(ans)); memset(num, 0, sizeof(num)); memset(sum, 0, sizeof(sum)); memset(head, -1, sizeof(head)); cnt=0;}void add(int u, int v){ e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt++;}void dfs(int u, int fa){ siz[u]=1; for(int i=head[u];~i;i=e[i].next){ if(e[i].to!=fa){ dfs(e[i].to, u); siz[u]+=siz[e[i].to]; if(rson[u]==-1)rson[u]=e[i].to; else { if(siz[e[i].to]>siz[rson[u]]){ lson[u]=rson[u]; rson[u]=e[i].to; } else { lson[u]=e[i].to; } } } }}int lowbit(int x){ return x&(-x);}void update(ll f[], int pos, int val){ while(pos<=tot){ f[pos]+=val; pos+=lowbit(pos); }}ll query(ll f[], int pos){ ll ans=0; while(pos){ ans+=f[pos]; pos-=lowbit(pos); } return ans;}void add(int u){ tmp+=(query(num, tot)-query(num, b[u]))*a[u]; tmp+=query(sum, b[u])+a[u]; update(num, b[u], 1); update(sum, b[u], a[u]);}void del(int u){ tmp-=(query(num, tot)-query(num, b[u]))*a[u]; tmp-=query(sum, b[u]); update(num, b[u], -1); update(sum, b[u], -a[u]);}void addtree(int u){ add(u); if(lson[u]!=-1)addtree(lson[u]); if(rson[u]!=-1)addtree(rson[u]);}void deltree(int u){ del(u); if(lson[u]!=-1)deltree(lson[u]); if(rson[u]!=-1)deltree(rson[u]);}void dfs1(int u){ if(lson[u]==-1){ if(rson[u]==-1){ add(u); ans[u]=tmp; return ; } dfs1(rson[u]); add(u); ans[u]=tmp; return; } dfs1(lson[u]); deltree(lson[u]); dfs1(rson[u]); addtree(lson[u]); add(u); ans[u]=tmp; return ;}int main(){ int T; scanf("%d", &T); while(T--){ init(); scanf("%d", &n); for(int i=1;i<=n;i++){ scanf("%d", &a[i]); id[i]=i; } sort(id+1, id+1+n, cmp); b[id[1]]=1; for(int i=2;i<=n;i++){ if(a[id[i]]==a[id[i-1]])b[id[i]]=b[id[i-1]]; else b[id[i]]=b[id[i-1]]+1; } tot=b[id[n]]; for(int i=1;i<n;i++){ int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } dfs(1, 0); dfs1(1); for(int i=1;i<=n;i++)printf("%lld ", ans[i]); printf("\n"); }}
阅读全文
0 0
- Hdu 6133 启发式合并
- hdu 4680 splay,启发式合并
- HDU 6133 Army Formations 树状数组 + 启发式合并
- HDU-6191 01字典树+启发式合并
- 启发式合并
- 【HDU】5197 DZY Loves Orzing 【FFT启发式合并】
- 【HDU 5997】 rausen loves cakes 【启发式合并+线段树】
- HDU 5997 rausen loves cakes (启发式合并+树状数组)
- [hdu 6191 Query on A Tree] 字典树启发式合并
- bzoj 1438(启发式合并)
- 树上启发式合并
- BZOJ2733 永无乡 [启发式合并]
- map + 启发式合并
- 树状数组+启发式合并
- 启发式合并&线段树合并&treap合并
- hdu 4670 Cube number on a tree,平衡树,启发式合并
- Hdu 3726 Graph and Queries(并查集+平衡树+启发式合并)
- HDU 5997 rausen loves cakes (线段树区间维护,启发式区间合并)
- POJ 2446 Chessboard(二分图最大匹配)
- sigaction()之sa_mask
- 深入理解计算机操作系统(2.3.3)
- Java中使用Future获取线程异步执行结果的使用
- Android动画知识汇总(初 xml篇)
- Hdu 6133 启发式合并
- Corejava day04
- Redis操作及持久化分析
- angularJs 中的ui-bootstrap 插件$uibModal 问题总结
- vue组件之间的通信
- Android开发 之 Path常用方法
- CSS 幽灵元素方案垂直居中注意事项
- Flask Web开发:基于Python的Web应用开发实战pdf
- 计算机系统知识