hdu 6133 树状数组+分类讨论
来源:互联网 发布:中行外汇行情分析软件 编辑:程序博客网 时间:2024/06/18 14:43
题意:。。比较复杂,就是一个树有点权,一个点的答案是子树的所有点权的前缀和的和(贪心思想转换后的题意),问所有答案。
首先这是个假题解。。只是提供一个思路。。。数据不强AC了。。。
思路:标解是个启发式合并。。这里尝试另一种做法(因为不会),平均时间复杂度是nlogn^2。(数据弱。。)考虑合并操作复杂,我们可以分为合并暴力,单个儿子直接得答案两种操作解决问题。(看起来很玄学。。),事实上是这样的,单个儿子的时间复杂度不用解释,肯定是正确的,我们只要维护子树离散化后的个数以及一个sum。对于暴力这部分。。其实也是一拍脑子想出来的。。首先有一个二叉结点我们就要暴力他的子树一次,当他是一个满二叉树的时候,整个排序的过程就类似一个归并树(事实上多一个sort的log),那么其实这个暴力就类似快排了,随机数据下时间复杂度是科学的。。
代码:
#include<bits/stdc++.h>using namespace std;#define MEM(a,b) memset(a,b,sizeof(a))#define bug puts("bug");#define PB push_back#define MP make_pair#define X first#define Y secondtypedef unsigned long long ll;typedef pair<int,int> pii;const int maxn=1e5+100;const int mod=1e9+7;using namespace std;ll sum;int id[maxn],L[maxn],R[maxn],x,y,n,t,tim,cnt[maxn];ll b[maxn],a[maxn],hs[maxn],bit[maxn],ans[maxn],sbit[maxn];vector<int> v[maxn];void add(int x,int y){ v[x].PB(y),v[y].PB(x);}int dfs(int x,int f){ int ret=1; L[x]=tim++; b[L[x]]=a[x]; for(int i=0;i<v[x].size();i++) if(v[x][i]!=f)ret+=dfs(v[x][i],x); R[x]=tim-1; return cnt[x]=ret;}int lowbit(int x){ return x&(-x);}void modify(int x,ll add,ll a[]){ while(x<maxn){ a[x]+=add; x+=lowbit(x); }}ll get_sum(ll x,ll a[]){ ll ret=0; while(x!=0){ ret+=a[x]; x-=lowbit(x); } return ret;}void del(int x,int f){ modify(id[x],-1,bit); modify(id[x],-a[x],sbit); for(int i=0;i<v[x].size();i++) if(v[x][i]!=f)del(v[x][i],x);}void addx(int x,int f){ modify(id[x],1,bit); modify(id[x],a[x],sbit); for(int i=0;i<v[x].size();i++) if(v[x][i]!=f)addx(v[x][i],x);}void sl(int x,int f){ vector<int> son; for(int i=0;i<v[x].size();i++) if(v[x][i]!=f)son.PB(v[x][i]); int siz=son.size(); if(siz==0)ans[x]=a[x]; else if(siz==1){ sl(son[0],x); ans[x]=ans[son[0]]+(get_sum(n+10,bit)-get_sum(id[x],bit))*a[x]+get_sum(id[x],sbit)+a[x]; } else if(siz==2){ int aa=0,bb=1; if(cnt[son[0]]>cnt[son[1]]) swap(aa,bb); sl(son[aa],x); del(son[aa],x); sl(son[bb],x); addx(son[aa],x); sort(b+L[x],b+R[x]+1); sum=0; for(int i=L[x];i<=R[x];i++)sum+=b[i],ans[x]+=sum; } modify(id[x],1,bit); modify(id[x],a[x],sbit);}int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); tim=1; MEM(sbit,0),MEM(bit,0);MEM(ans,0);MEM(cnt,0); for(int i=0;i<=n+2;i++) v[i].clear(); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=n;i++) hs[i]=a[i]; sort(hs+1,hs+n+1); int N=unique(hs+1,hs+n+1)-hs; for(int i=1;i<=n;i++) id[i]=lower_bound(hs+1,hs+N,a[i])-hs+1; for(int i=0;i<n-1;i++) scanf("%d%d",&x,&y),add(x,y); dfs(1,-1); sl(1,-1); for(int i=1;i<=n;i++) printf("%lld ",ans[i]); puts(""); }}
阅读全文
0 0
- hdu 6133 树状数组+分类讨论
- 8-30(高斯,树状数组,分类讨论,stl)
- HDU 6133 Army Formations(树状数组)
- HDU 1394 树状数组
- 树状数组 hdu
- hdu 1166 树状数组
- HDU 2838 树状数组
- hdu 2492【树状数组】
- hdu 3015【树状数组】
- hdu 3874 树状数组
- hdu 3874(树状数组)
- hdu 3890 树状数组
- 【树状数组】hdu 2852
- 【树状数组】hdu 4000
- HDU 4046 树状数组
- hdu 1166(树状数组)
- HDU-3887-树状数组
- hdu 4358树状数组
- 斐波那契数列
- 图的基本存储的基本方式一(邻接矩阵)
- CodeForces
- LeetCode No.24 Swap Nodes in Pairs
- 最简单的条件判断程序
- hdu 6133 树状数组+分类讨论
- 2017.08.18总结
- CF549C
- hdu 1556 Color the ball(区间更新,查询点)
- 2017年8月18日训练日记
- 公网ip访问服务器网站(博客)
- C语言之常见错误解决办法
- 高并发解决方案
- 文章标题