HDU 5664 Lady CA and the graph 二分,树分治
因为要不断二分,所以事先进行树分治的预处理,这样接下来就是计数的操作了,减少了复杂度。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define MS(x,y) memset(x,y,sizeof(x))
#define PB push_back
#define lowbit(x) (x&(-x))
typedef long long LL;
const int MAXN=5e4+5;
struct Edge{int v,w,nxt;
}edge[MAXN<<1];
int head[MAXN],edgenum;
void addedge(int u,int v,int w){edge[edgenum].v=v;edge[edgenum].w=w;edge[edgenum].nxt=head[u];head[u]=edgenum++;
}
int n,m,k;
vector<int> G[MAXN*15],que[MAXN];
int cnt1,cnt2,Root;bool used[MAXN];
int siz[MAXN];
int root,w;
void dfsroot(int u,int f,int num){siz[u]=1;int K=0;for(int i=head[u];~i;i=edge[i].nxt){int &v=edge[i].v;if(used[v]||v==f) continue;dfsroot(v,u,num);K=max(K,siz[v]);siz[u]+=siz[v];}K=max(K,num-siz[u]);if(K<w) root=u,w=K;
}
void dfsdist(int u,int f,int w){G[cnt1].PB(w);for(int i=head[u];~i;i=edge[i].nxt){int &v=edge[i].v;if(used[v]||v==f) continue;dfsdist(v,u,w+edge[i].w);}
}
void Cal(int u,int w){++cnt1;dfsdist(u,0,w);sort(G[cnt1].begin(),G[cnt1].end());
}
void Work(int u){Cal(u,0);used[u]=true;for(int i=head[u];~i;i=edge[i].nxt){int &v=edge[i].v;if(used[v]) continue;Cal(v,edge[i].w);w=siz[v];root=0;dfsroot(v,0,siz[v]);que[u].PB(root);Work(root);}
}
void init(){for(int i=1;i<=n*10;++i) G[i].clear();for(int i=1;i<=n;++i) que[i].clear();cnt1=cnt2=0;MS(used,false);root=1;w=n;dfsroot(1,0,n);Root=root;Work(root);
}int tr[MAXN<<1],hsh[MAXN<<1];
LL Ans;
int cnt3;
void add(int x,int v){for(;x<MAXN*2;x+=lowbit(x)) tr[x]+=v;
}
LL query(int x){LL ret=0;for(;x;x-=lowbit(x)) ret+=tr[x];return ret;
}
LL cal(int mid){LL ret=0;++cnt2;int num=G[cnt2].size()-1,r=num;for(int i=0;i<num;++i){r=max(i+1,r);while(r>i+1&&G[cnt2][r-1]+G[cnt2][i]>=mid) --r;if(G[cnt2][r]+G[cnt2][i]<mid) continue;ret+=(num-r+1);}return ret;
}
void work(int u,int mid){Ans+=cal(mid);used[u]=true;int x=0;for(int i=head[u];~i;i=edge[i].nxt){int &v=edge[i].v;if(used[v]) continue;Ans-=cal(mid);work(que[u][x++],mid);}
}
void dfs1(int u,int f,int w,int mid){hsh[++cnt3]=w;hsh[++cnt3]=w-mid;for(int i=head[u];~i;i=edge[i].nxt){int &v=edge[i].v;if(v==f) continue;dfs1(v,u,w+edge[i].w,mid);}
}
void dfs2(int u,int f,int w,int mid){int num1=lower_bound(hsh+1,hsh+cnt3+1,w-mid)-hsh;int num2=lower_bound(hsh+1,hsh+cnt3+1,w)-hsh;Ans-=query(num1);add(num2,1);for(int i=head[u];~i;i=edge[i].nxt){int &v=edge[i].v;if(v==f) continue;dfs2(v,u,w+edge[i].w,mid);}add(num2,-1);
}
bool check(int mid,int k){Ans=0;MS(used,false);cnt2=0;work(Root,mid);MS(tr,0);cnt3=0;dfs1(m,0,0,mid);sort(hsh+1,hsh+cnt3+1);cnt3=unique(hsh+1,hsh+cnt3+1)-hsh-1;dfs2(m,0,0,mid);return Ans>=k;
}int main(){int T;scanf("%d",&T);while(T--){MS(head,-1);edgenum=0;scanf("%d%d%d",&n,&m,&k);int u,v,w,maxw=0;for(int i=1;i<n;++i){scanf("%d%d%d",&u,&v,&w);addedge(u,v,w);addedge(v,u,w);maxw=max(maxw,w);}init();int l=0,r=n*maxw,mid,ans=0;while(l<=r){mid=(l+r)>>1;if(check(mid,k)) l=mid+1,ans=mid;else r=mid-1;}if(ans==0) puts("NO");else printf("%d\n",ans);}
}
HDU 5664 Lady CA and the graph 二分,树分治相关推荐
- 牛客多校5 - Graph(字典树+分治求最小生成树)
题目链接:点击查看 题目大意:给出一棵树,每条边都有一个权值,每次操作可以删除任意一条边或者增加任意权值的一条边,现在可以执行数次操作,不过任何时间都要满足以下两个条件: n 个点互相连通 所有环的权 ...
- 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...
- jzoj4050-寻宝游戏【二分,树状数组,LCA】
正题 题目链接:https://jzoj.net/senior/#contest/show/3017/1 题目大意 nnn个点的一棵树,mmm次操作,修改一个地方的宝藏. 每次操作后求拿完所以宝藏并回 ...
- bzoj4418 [Shoi2013]扇形面积并 扫描线+二分+树状数组
Description 给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖. 对于100%的数据,1≤n≤105, 1≤m≤106,1≤k≤5000,1≤ri≤105,-m≤a1,a2≤m Sol ...
- HDU 4282 A very hard mathematic problem 二分题目
http://acm.hdu.edu.cn/showproblem.php?pid=4282 题解:http://www.cnblogs.com/E-star/archive/2012/09/11/2 ...
- hdu 1054 Strategic Game 最小点覆盖 = 最大二分匹配
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1054 简单二分匹配,根据题意构造一个无向图.然后求最小点覆盖,然后扫描mark数组将曾经匹配的点所匹配 ...
- hdu 2141 Can you find it(二分)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2141 题意:给出三个数列a,b,c和一组数x,求对于每个x是否存在 ai + bj + ck = x;其中 ...
- hdu 4430 Yukari's Birthday (简单数学 + 二分)
Problem - 4430 题意是,给出蜡烛的数量,要求求出r和k,r是蜡烛的层数,k是每一层蜡烛数目的底数. 开始的时候,没有看清题目,其实中间的那根蜡烛是可放可不放的.假设放置中间的那根蜡烛,就 ...
- HDU多校1 - 6756 Finding a MEX(分块+二分+树状数组)
题目链接:点击查看 题目大意:给出一个 n 个点和 m 条边的无向图,每个点都有一个权值,现在需要执行 q 次操作,每次操作分为两种类型: 1 pos val :将第 pos 个点的权值修改为 val ...
最新文章
- 影响数据库性能的因素
- 搞怪菜鸟加入域全程图解[为企业部署Windows Server 2008系列十二]
- circle后面是什么意思 python_Ape circle Python操作-第2-01章-列表操作,小猿圈,作业
- python pip清华源安装库
- Xilinx PCIE IP核接口介绍
- 6400万像素时代来了,小米首个入局
- 十三种寂寞 你有过吗?『最无奈的是第13种』
- 恢复触摸板功能的方法
- Unity3D资源加载Resources
- 普元EOS之性能调优
- 视频剪辑-mkv文件导入PR
- 手写板(数位板)如何和希沃白板5无缝切换
- cesium label和billboard 的一些配置注释
- 排队系统拥塞控制的位置
- asyncore斗鱼弹幕抓取
- GC overhead limit exceeded问题
- 机器人运动学标定:基于指数积的串联机构运动学标定
- 运动图像目标检测与跟踪简述
- css3字体闪烁炫酷,css3 scale动画 字体、输入框等会闪烁,怎么解决?
- Python3.9版本发布,不同领域的程序员如何学Python?