894D - Ralph And His Tour in Binary Country 完全二叉树点对计数
打完模拟被xz忽悠去码,粗略听了一波题解之后开始搞
总体感觉自己码力确实有进步了。。起码遇到啥问题了会找地方改,改啥肯定能出想要的效果。。
好像别人的代码都很短啊?我感觉自己这版写的逻辑挺清楚的。。就是长了点。。
一点一点实现自己脑内搭建的逻辑还是挺愉快的。。
//#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const int maxn=1e6+9; int n,m; struct NODE{ int u; int d; }; ll falen[maxn]; //父边长度 vector<NODE>G[maxn]; vector<NODE>son[maxn]; int check(int now,ll H){ int l=0,r=son[now].size()-1; int ans=-1; while(l<=r){ int m=l+r>>1; if(son[now][m].d<=H){ l=m+1; ans=max(ans,m); }else{ r=m-1; } } return ans; } vector<ll>presum[maxn]; void work(int A,ll H){ ll ans=0; int nowA=A; ll nowH=H,nowL=0;//登记当前根,需要长度,已有长度 int pre=-1; int pos=check(nowA,nowH); ans+=(pos+1)*H-presum[nowA][pos]; nowL+=falen[nowA]; nowH-=falen[nowA]; pre=nowA; nowA>>=1; while(nowA && nowH>=0){ //cout<<nowA<<" "<<ans<<endl; int pos;int ned; if(pre%2){ ned=pre-1; pos=check(ned,nowH-G[nowA][0].d); }else{ ned=pre+1; pos=check(ned,nowH-G[nowA][1].d); } if(pos!=-1){ if(pre%2==0)ans+=(pos+1)*(nowH-G[nowA][1].d)-presum[ned][pos]; else ans+=(pos+1)*(nowH-G[nowA][0].d)-presum[ned][pos]; } ans+=nowH; nowL+=falen[nowA]; nowH-=falen[nowA]; pre=nowA; nowA>>=1; } printf("%lld\n",ans); } void dfs(int u){ son[u].pb((NODE){u,0}); presum[u].pb(0); if(G[u].size()==0)return; for(int i=0;i<G[u].size();i++){ int v=G[u][i].u; ll w=G[u][i].d; dfs(v); } if(G[u].size()==1){ int v=G[u][0].u;ll w=G[u][0].d; for(int i=0;i<son[G[u][0].u].size();i++){ son[u].pb((NODE){son[v][i].u,son[v][i].d+w}); presum[u].pb(son[v][i].d+w+presum[u][presum[u].size()-1]); } return; } int pl=0,pr=0; while(pl!=son[G[u][0].u].size() || pr!=son[G[u][1].u].size()){ if(pl==son[G[u][0].u].size()){ int v=G[u][1].u; ll w=G[u][1].d; for(;pr!=son[G[u][1].u].size();pr++){ son[u].pb((NODE){son[v][pr].u,son[v][pr].d+w}); presum[u].pb(son[v][pr].d+w+presum[u][presum[u].size()-1]); } break; } if(pr==son[G[u][1].u].size()){ int v=G[u][0].u; ll w=G[u][0].d; for(;pl!=son[G[u][0].u].size();pl++){ son[u].pb((NODE){son[v][pl].u,son[v][pl].d+w}); presum[u].pb(son[v][pl].d+w+presum[u][presum[u].size()-1]); } break; } int v1=G[u][0].u,v2=G[u][1].u; ll w1=G[u][0].d,w2=G[u][1].d; if(son[v1][pl].d+w1 <= son[v2][pr].d+w2){ son[u].pb((NODE){son[v1][pl].u,son[v1][pl].d+w1}); presum[u].pb(son[v1][pl].d+w1+presum[u][presum[u].size()-1]); pl++; continue; }else{ son[u].pb((NODE){son[v2][pr].u,son[v2][pr].d+w2}); presum[u].pb(son[v2][pr].d+w2+presum[u][presum[u].size()-1]); pr++; continue; } } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ ll x; scanf("%d",&x); G[(i+1)/2].pb((NODE){i+1,x}); falen[i+1]=x; } dfs(1); int A;ll H; while(m--){ scanf("%d%lld",&A,&H); work(A,H); } }