完全二叉树+暴力预处理+归并排序——cf894D
Posted zsben991126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了完全二叉树+暴力预处理+归并排序——cf894D相关的知识,希望对你有一定的参考价值。
/* 结点i的左儿子是2i,右儿子是2i+1 那么显然这是一棵完全二叉树。 由于没有很好直接查询的办法,所以先考虑预处理一下这棵树 根据完全二叉树的性质,sum{size[i]}<=nlogn,所以直接用vector存下结点的所有孩子,自底向上对到子树距离归并排序 这样预处理完后,对于每个询问(A,H),我们只要以A为起点不断向上爬(最多logn次),通过lower_bound来计算贡献 */ #include<bits/stdc++.h> #include<vector> using namespace std; #define N 1000005 #define ll long long struct Edge{ ll to,nxt,w; }e[N<<1]; int head[N],tot; void init(){ memset(head,-1,sizeof head); tot=0; } void add(int u,int v,ll w){ e[tot].to=v;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot++; } vector<ll>dis[N]; int n,m; vector<ll> merge(vector<ll> & fa, vector<ll> & son,ll w){ vector<ll>res;res.clear(); int p1=0,p2=0; while(1){ if(fa[p1]<=son[p2]+w){ res.push_back(fa[p1]); ++p1; } else { res.push_back(son[p2]+w); ++p2; } if(p1==fa.size() || p2==son.size())break; } while(p1<fa.size()) res.push_back(fa[p1]),p1++; while(p2<son.size()) res.push_back(son[p2]+w),p2++; return res; } void dfs(int u,int pre){ int son=0; for(int i=head[u];i!=-1;i=e[i].nxt){ int v=e[i].to; if(v==pre)continue; son++;dfs(v,u); } dis[u].push_back(0); if(son==0)return; for(int i=head[u];i!=-1;i=e[i].nxt){ int v=e[i].to; if(v==pre)continue; dis[u]=merge(dis[u],dis[v],e[i].w); } } vector<ll>sum[N]; void sumup(){ for(int i=1;i<=n;i++)sum[i]=dis[i]; for(int i=1;i<=n;i++){ for(int j=1;j<sum[i].size();j++) sum[i][j]+=sum[i][j-1]; } } ll W[N]; ll query(int u,ll H){//在子树u下查询 if(H<=0)return 0; ll res=0; int pos=lower_bound(dis[u].begin(),dis[u].end(),H)-dis[u].begin(); if(pos==0)return 0; pos--; res=H*(pos+1)-sum[u][pos]; return res; } int main(){ cin>>n>>m; init(); for(int i=1;i<n;i++){ ll w;scanf("%lld",&w); add((i+1)/2,i+1,w); add(i+1,(i+1)/2,w); W[i+1]=w; } dfs(1,1); sumup(); while(m--){ ll A,H; scanf("%lld%lld",&A,&H); ll sum=query(A,H); while(1){ H-=W[A]; if(A==1 || H<=0)break; int tmp=A; A/=2;//A=fa[A] sum+=H; for(int i=head[A];i!=-1;i=e[i].nxt){ int v=e[i].to; if(v==tmp||v<A)continue; sum+=query(v,H-e[i].w); } } cout<<sum<<‘ ‘; } }
以上是关于完全二叉树+暴力预处理+归并排序——cf894D的主要内容,如果未能解决你的问题,请参考以下文章