洛谷 4178 Tree——点分治
题目:https://www.luogu.org/problemnew/show/P4178
点分治。如果把每次的 dis 和 K-dis 都离散化,用树状数组找,是O(n*logn*logn),会T7个点。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=4e4+5; int n,hd[N],xnt,to[N<<1],nxt[N<<1],w[N<<1],f[N<<1],siz[N],ans,mn,rt; ll dis[N],tis[N],tp[N<<1],tnt,K; bool vis[N],sj[N]; void add(int x,int y,ll z) {to[++xnt]=y;nxt[xnt]=hd[x];w[xnt]=z;hd[x]=xnt;to[++xnt]=x;nxt[xnt]=hd[y];w[xnt]=z;hd[y]=xnt; } void getrt(int cr,int fa,int s) {siz[cr]=1;int mx=0;for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa){getrt(v,cr,s);siz[cr]+=siz[v];mx=max(mx,siz[v]);}mx=max(mx,s-siz[cr]);if(mx<mn)mn=mx,rt=cr; } void add(int x){for(;x<=tnt;x+=(x&-x))f[x]++;} int query(int x){int ret=0;for(;x;x-=(x&-x))ret+=f[x];return ret;} void dfs(int cr,int fa,ll lj) {dis[cr]=lj;sj[cr]=1;for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa)dfs(v,cr,lj+w[i]); } int calc(int cr,ll w) {memset(sj,0,sizeof sj);tnt=0;dfs(cr,0,w);for(int i=1;i<=n;i++) if(sj[i]&&dis[i]<=K){tis[i]=K-dis[i];tp[++tnt]=dis[i];tp[++tnt]=tis[i]; // printf("dis[%d]=%lld tis[%d]=%lld\n",i,dis[i],i,tis[i]); }sort(tp+1,tp+tnt+1);tnt=unique(tp+1,tp+tnt+1)-tp-1;int ret=0;for(int i=1;i<=n;i++) if(sj[i]&&dis[i]<=K){dis[i]=lower_bound(tp+1,tp+tnt+1,dis[i])-tp;tis[i]=lower_bound(tp+1,tp+tnt+1,tis[i])-tp; // printf("dis[%d]=%lld tis[%d]=%lld\n",i,dis[i],i,tis[i]);ret+=query(tis[i]);add(dis[i]);}memset(f,0,sizeof f);return ret; } void solve(int cr,int s) { // printf("rt=%d\n",cr);vis[cr]=1;ans+=calc(cr,0); // printf("cr=%d ans=%d\n",cr,ans);for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]){ans-=calc(v,w[i]);int ts=(siz[cr]>siz[v]?siz[v]:s-siz[cr]);//-siz[cr]!!!mn=N;getrt(v,0,ts);solve(rt,ts);} } int main() {scanf("%d",&n);int x,y;ll z;for(int i=1;i<n;i++){scanf("%d%d%lld",&x,&y,&z);add(x,y,z);}scanf("%lld",&K);mn=N;getrt(1,0,n);solve(rt,n);printf("%d\n",ans);return 0; }
View Code
应当排序后枚举两个指针。(代码中两种方法时间一样)
如果把 ts=s-siz[cr] 写成 ts=s-siz[v] ,就会T7个点(?)!!!
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=4e4+5; int n,hd[N],xnt,to[N<<1],nxt[N<<1],w[N<<1],siz[N],mn,rt,sta[N],top,K,ans; bool vis[N]; void add(int x,int y,int z) {to[++xnt]=y;nxt[xnt]=hd[x];w[xnt]=z;hd[x]=xnt;to[++xnt]=x;nxt[xnt]=hd[y];w[xnt]=z;hd[y]=xnt; } void getrt(int cr,int fa,int s) {siz[cr]=1;int mx=0;for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa){getrt(v,cr,s);siz[cr]+=siz[v];mx=max(mx,siz[v]);}mx=max(mx,s-siz[cr]);if(mx<mn)mn=mx,rt=cr; } void dfs(int cr,int fa,int lj) {sta[++top]=lj;for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa)dfs(v,cr,lj+w[i]); } int calc(int cr,int w) {int ret=0;dfs(cr,0,w); // l=1;r=0; // sort(sta+l,sta+r+1); // while(l<=r) // if(sta[l]+sta[r]<=K)ret+=r-l,l++; // else r--;sort(sta+1,sta+top+1);int p=top;for(int i=1;i<=top;i++){while(sta[p]+sta[i]>K&&p)p--;if(!p)break;ret+=p-(p>=i);}top=0; // printf("cr=%d ret=%d\n",cr,ret);return ret>>1; } void solve(int cr,int s) { // printf("rt=%d\n",cr);vis[cr]=1;ans+=calc(cr,0); // printf("cr=%d ans=%d\n",cr,ans);for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]){ans-=calc(v,w[i]);int ts=(siz[cr]>siz[v]?siz[v]:s-siz[cr]);//s-siz[cr]!!!mn=N;getrt(v,0,ts);solve(rt,ts);} } int main() {scanf("%d",&n);for(int i=1,x,y,z;i<n;i++){scanf("%d%d%d",&x,&y,&z);add(x,y,z);}scanf("%d",&K);mn=N;getrt(1,0,n);solve(rt,n);printf("%d\n",ans);return 0; }
转载于:https://www.cnblogs.com/Narh/p/9478066.html
洛谷 4178 Tree——点分治相关推荐
- 洛谷T44252 线索_分治线段树_思维题
分治线段树,其实就是将标记永久化,到最后再统一下传所有标记. 至于先后顺序,可以给每个节点开一个时间戳. 一般地,分治线段树用于离线,只查询一次答案的题目. 本题中,标记要被下传 222 次. Cod ...
- 洛谷 P1498 南蛮图腾 分治递归过程详解
题目描述 自从到了南蛮之地,孔明不仅把孟获收拾的服服帖帖,而且还发现了不少少数民族的智慧,他发现少数民族的图腾往往有着一种分形的效果,在得到了酋长的传授后,孔明掌握了不少绘图技术,但唯独不会画他们的图 ...
- 洛谷 P2400 秘密文件【分治】
... 题目: 题意: 分析: 代码: 题目: 传送门 题意: 给出一个较长的字符串,要求我们按照规则进行化简,使得其长度最短 分析: 直接使用分治的思想,对于区间l−rl-rl−r,我们枚举一个分界 ...
- 洛谷 4115 Qtree4——链分治
题目:https://www.luogu.org/problemnew/show/P4115 论文:https://wenku.baidu.com/view/1bc2e4ea172ded630b1cb ...
- [WC2005]双面棋盘,洛谷P4121,线段树分治+可撤销并查集
正题 这题主要是来练手的,因为没写过可撤销的并查集,大概就是把每一个格子看成一个点,然后格子直接的边有很多的出现区间,把这些出现区间和对应的颜色打到线段树上,然后用可撤销的并查集来维护就可以了. #i ...
- 【洛谷习题】南蛮图腾
题目链接:https://www.luogu.org/problemnew/show/P1498 不好实现... 这道题在洛谷的分类是分治,我用的方法就是分治,不过却刷新的我对分治的认识.以前见过的分 ...
- Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)
题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...
- 分治——Secret Cow Code S(洛谷 P3612)
题目选自洛谷P3612 梳理题意 给定一个字符串,每次将其最后一个字符移到最前方,形成的新串接到原串后作为下一次操作的字符串 现询问第 N 个位置的字符 简要分析 看一眼数据范围,N<10^18 ...
- BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...
最新文章
- 字符串-拆分和拼接字符串
- Linux系统运维成长记
- java abs前缀变量_JAVA工具例大全--cn.hutool.setting.AbsSetting读取配置文件例子
- Go实现Raft第四篇:持久化和调优
- JTS(Geometry)工具类
- [转]ubuntu系统瘦身-清理系统垃圾文件
- Mac系统升级node
- 学用 ASP.Net 之 System.Collections.Specialized.StringDictionary 类
- linux acpidtd 进程,clover引导卡在该图上了,求资助
- JavaWeb在线商城系统(java+jsp+servlet+MySQL+jdbc+css+js+jQuery)
- linux netperf,Netperf性能测试工具
- MDM主数据管理平台开发精要
- 【编译原理】理解BNF
- 网聚云联受邀出席5G和边缘计算高峰论坛,与清华研究院达成战略合作
- 程序猿、公关狗、设计狮……知道你们年底苦,该去京东生鲜补补了
- 车载信息系统平台的未来发展
- c语言程序设计 学籍,c语言学籍信息管理系统设计
- 显示器扩展后左右如何设置?
- Git入门基础-Chivalrous-专题视频课程
- iPad最值得期待的切实改进构想
热门文章
- CSS3实现8种Loading效果【第二波】
- 反应堆模式最牛的那篇论文--由solidmango执笔翻译
- ZH奶酪:自然语言处理工具LTP语言云调用方法
- .NET Remoting 入门实例
- [转]javascript 判断某页面上的表单数据是否改变过
- AndroidStudio安卓原生开发_Activity的IntentFlag的SINGLE_TOP_CLEAR_TOP_REORDER_TO_FRONT的用法---Android原生开发工作笔记90
- 快速开发框架工作笔记002---项目开发中整理_整合好的_Netty高并发处理快速开发框架_Netty快速开发框架
- 持续集成部署Jenkins工作笔记0014---curl命令触发构建
- ASP.NET工作笔记014---用VB.NET封装服务器端控件
- senet-运行和结构篇