【bzoj1146】 [CTSC2008]网络管理Network【树链剖分+树套树+二分 线段树套Treap】
1146: [CTSC2008]网络管理Network
Description
Input
Output
蒟弱写的第一篇blog,好兴奋!
思路:树链剖分+树套树。
首先树链剖分一下,接下来线段树套Treap,修改时就在线段树上走一下,删除原来的值并且插入新的值。查询时,二分答案,求mid的排名,逐渐向答案逼近。查询排名,就是求比这个数小的数的个数+1。为了效率不至于太低,我离散化了一下。细节详见代码。时间复杂度线段树一个log,Treap还有一个log,查询还有树剖1个log,二分1个log。因此修改是2个log,查询是4个log,总时间复杂度O(nlog^4n)。 码得好爽啊,260行代码居然没有调试,1A。但是。。。。。。这份代码跑得像shi一样慢,30s+。废话4个log能跑多快。
代码:
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline int rd()
{char ch=getchar();int ret=0,f=1;while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}return ret*f;
}
const int N=80005;
int n,q,u,v,cnt=0,idx=0,tot=0,ans,a[N],hash[N*2],K[N],A[N],B[N],root[N*4];
int head[N],to[N*2],nxt[N*2],size[N],son[N],dep[N],fa[N],pos[N],top[N];
int mempool[N*20],key[N*20],rnd[N*20],siz[N*20],w[N*20],ch[N*20][2];
int ins,rmv;
int getid(int x)
{return lower_bound(hash+1,hash+hash[0]+1,x)-hash;
}
void adde(int u,int v)
{to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
}
void dfs1(int u)
{size[u]=1;for(int v=head[u];v;v=nxt[v])if(to[v]!=fa[u]){fa[to[v]]=u;dep[to[v]]=dep[u]+1;dfs1(to[v]);size[u]+=size[to[v]];if(!son[u]||size[son[u]]<size[to[v]])son[u]=to[v];}
}
void dfs2(int u,int tp)
{pos[u]=++idx;top[u]=tp;if(son[u]) dfs2(son[u],tp);for(int v=head[u];v;v=nxt[v])if(to[v]!=fa[u]&&to[v]!=son[u])dfs2(to[v],to[v]);
}
void maintain(int k)
{siz[k]=siz[ch[k][0]]+siz[ch[k][1]]+w[k];
}
void rturn(int &k)
{int t=ch[k][0];ch[k][0]=ch[t][1];ch[t][1]=k;siz[t]=siz[k];maintain(k);k=t;
}
void lturn(int &k)
{int t=ch[k][1];ch[k][1]=ch[t][0];ch[t][0]=k;siz[t]=siz[k];maintain(k);k=t;
}
void insert(int &k,int x)
{if(!k){k=mempool[mempool[0]--];key[k]=x;rnd[k]=rand();siz[k]=w[k]=1;ch[k][0]=ch[k][1]=0;return;}siz[k]++;if(x==key[k]) w[k]++;else if(x<key[k]){insert(ch[k][0],x);if(rnd[ch[k][0]]<rnd[k]) rturn(k);}else{insert(ch[k][1],x);if(rnd[ch[k][1]]<rnd[k]) lturn(k);}
}
void remove(int &k,int x)
{if(x==key[k]){if(w[k]>1){siz[k]--;w[k]--;return;}else if(ch[k][0]*ch[k][1]==0){mempool[++mempool[0]]=k;if(!ch[k][0]) k=ch[k][1];else k=ch[k][0];}else{if(rnd[ch[k][0]]>rnd[ch[k][1]]) lturn(k);else rturn(k);remove(k,x);}}else{siz[k]--;if(x<key[k]) remove(ch[k][0],x);else remove(ch[k][1],x);}
}
void rnk(int k,int x)
{while(k){if(x<=key[k]) k=ch[k][0];else{ans+=siz[ch[k][0]]+w[k];k=ch[k][1];}}
}
void build(int o,int l,int r,int k)
{insert(root[o],ins);if(l==r) return;int mid=(l+r)/2;if(k<=mid) build(o*2,l,mid,k);else build(o*2+1,mid+1,r,k);
}
void change(int o,int l,int r,int k)
{remove(root[o],rmv);insert(root[o],ins);if(l==r) return;int mid=(l+r)/2;if(k<=mid) change(o*2,l,mid,k);else change(o*2+1,mid+1,r,k);
}
void query(int o,int l,int r,int L,int R,int k)
{if(L<=l&&R>=r){rnk(root[o],k);return;}int mid=(l+r)/2;if(L<=mid) query(o*2,l,mid,L,R,k);if(R>mid) query(o*2+1,mid+1,r,L,R,k);
}
int LCA(int u,int v)
{while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);u=fa[top[u]];}if(dep[u]>dep[v]) swap(u,v);return u;
}
void solvequery(int u,int v,int k)
{while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);query(1,1,n,pos[top[u]],pos[u],k);u=fa[top[u]];}if(dep[u]>dep[v]) swap(u,v);query(1,1,n,pos[u],pos[v],k);
}
int main()
{for(int i=1600000;i>=1;i--) mempool[++mempool[0]]=i;n=rd(),q=rd();for(int i=1;i<=n;i++)hash[++hash[0]]=a[i]=rd();for(int i=1;i<n;i++){scanf("%d%d",&u,&v);adde(u,v);adde(v,u);}dfs1(1);dfs2(1,1);for(int i=1;i<=q;i++){K[i]=rd(),A[i]=rd(),B[i]=rd();if(!K[i]) hash[++hash[0]]=B[i];}sort(hash+1,hash+hash[0]+1);hash[0]=unique(hash+1,hash+hash[0]+1)-hash-1;for(int i=1;i<=n;i++){ins=getid(a[i]);build(1,1,n,pos[i]);}for(int i=1;i<=q;i++){if(!K[i]){ins=getid(B[i]);rmv=getid(a[A[i]]);change(1,1,n,pos[A[i]]);a[A[i]]=B[i];}else{int lca=LCA(A[i],B[i]),siz=dep[A[i]]+dep[B[i]]-dep[lca]*2+1;if(siz<K[i]){puts("invalid request!");continue;}K[i]=siz-K[i]+1;int l=1,r=hash[0],tmp;while(l<=r){int mid=(l+r)/2;ans=1;solvequery(A[i],B[i],mid);if(ans<=K[i]){l=mid+1;tmp=mid;}else r=mid-1;}printf("%d\n",hash[tmp]);}}return 0;
}
转载于:https://www.cnblogs.com/2016gdgzoi471/p/9476919.html
【bzoj1146】 [CTSC2008]网络管理Network【树链剖分+树套树+二分 线段树套Treap】相关推荐
- BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...
- 树链剖分 or 根号分治 + dfs序 + 树状数组 ---- CF1254 D. Tree Queries
题目链接 题目大意: 问题转化: 很容易发现:假设修改的节点是vvv. 1.vvv的子树sonvson_vsonv直接加上(n−size[sonv])n×d\frac{(n-size[son_v]) ...
- 树剖+线段树||树链剖分||BZOJ1984||Luogu4315||月下“毛景树”
题面:月下"毛景树" 题解:是道很裸的树剖,但处理的细节有点多(其实是自己线段树没学好).用一个Dfs把边权下移到点权,用E数组记录哪些边被用到了:前三个更新的操作都可以合并起来, ...
- BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...
- SPOJ - QTREE3Query on a tree again!——树链剖分
[题目描述] SPOJ - QTREE3Query on a tree again! [题目分析] 题目要求是输出从111到xxx的路径上遇到的第一个黑色的点.我们可以用树链剖分(不了解的同学请出门左 ...
- bzoj 3626: [LNOI2014]LCA(离线差分+树链剖分)
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2885 Solved: 1133 [Submit][Sta ...
- HDU 3966 POJ 3237 HYSBZ 2243 HRBUST 2064 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- E. Tree(The 2019 ACM-ICPC China Shannxi Provincial Programming Contest)(树链剖分+线段树)
4000ms 262144K judge:计蒜客 Description Ming and Hong are playing a simple game called nim game. They h ...
- 树链剖分(轻重链)入门
写在前面 仅想学树剖LCA的同学其实不必要了解线段树 前置知识:树形结构,链式前向星(熟练),线段树(熟练),DFS序(熟练),LCA(了解定义) 树链剖分(树剖):将树分解为一条条不相交的,从祖先到 ...
最新文章
- stm32编码器正反转计数程序_编码器接线方法你会吗?
- War包与配置文件分离
- E2. 比昨天更多的棒棒糖 (Hard)
- go reflect 取指针_Go的方法集详解
- mybatis-通用Mapper
- 使用 systemd 定时器调度任务
- 1.数据结构 --- 绪论
- opencv-python版本问题
- 网站html导出excel插件,使用JQuery插件将HTML的table标签数据导出成excel
- 优启通制作系统u盘_优启通 v3.6.2020.0620 VIP版/免费版-好用的U盘启动盘制作工具...
- 程序员的超强本地构建工具
- SLAM之PTAM学习笔记
- 最小二乘法曲线拟合(代码环境:matlab)
- Aptana 安装与配置
- C++幕后故事(七)--一个对象的生与死
- 2022-2027年中国微创介入医疗器械市场竞争态势及行业投资前景预测报告
- MP4视频太大怎么在线压缩
- 讯飞实时语音转写 python3.6.1 可完美运行 解析返回的json字符串 输出所获语音文字
- 主板和机箱螺丝孔对不上?
- zuk z2 android 7.0,联想ZUK Z2兑现承诺,即将推出安卓7.0更新