CF1399E2 Weights Division (hard version) 题解
对于两种权值的分别贪心维护,最后枚举一种权值选多少个,另一个二分出来,总复杂度 \(2\log\)。
点击查看代码
#include
#include
#include
typedef long long ll;
inline int min(const int &a,const int &b){return a t1,t2;
inline void add_edge(int u,int v,int w,int c){e[++tot]=(Edge){v,w,c,h[u]};h[u]=tot;}
void dfs(int u,int fa){
bool son=0;
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v;if(v==fa) continue;
val[v]=e[i].w,cost[v]=e[i].c;
dfs(v,u);siz[u]+=siz[v],son=1;
}
if(!son) siz[u]=1;
}
int main(){int T;scanf("%d",&T);while(T--){
scanf("%d%lld",&n,&S);
for(int i=1;i<=n;++i) h[i]=siz[i]=0;tot=0;
for(int i=1;i>=1;
if(val[u]) t1.push(Node(u));
}
while(!t2.empty()){
int u=t2.top().x;t2.pop();
a2[++cnt2]=a2[cnt2-1]+((ll)val[u]+1)/2*siz[u];
val[u]>>=1;
if(val[u]) t2.push(Node(u));
}
int ans=INF;
for(int i=0;i<=cnt1;++i){
if(Sum-a1[i]<=S){ans=min(ans,i);break;}
if(Sum-a1[i]-a2[cnt2]>S) continue;
int l=0,r=cnt2;
while(l>1;
if(Sum-a1[i]-a2[mid]<=S) r=mid;
else l=mid+1;
}
ans=min(ans,i+2*l);
}
printf("%d\n",ans);
}
return 0;
}