【BZOJ 1146】[CTSC2008]网络管理Network
树剖+树状数组套线段树O(nlogn^3)(我打的),有一种更加优秀的算法是O(nlogn^2)的就是直接树状数组套线段树欧拉序(并不快),或者是用主席树维护原始的树的信息,同时用树状数组套线段树维护dfs序上的修改(很优秀),这道题将树上信息转化为序列信息,并在此基础之上用任意树套树,只不过转化的方式不一样,要么是树剖,要么是树上差分(dfs序或者欧拉序都可以)
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mid ((l+r)>>1)
#define newnode (node+(sz++))
const int N=;
const int Inf=;
char xB[(<<)+],*xS=xB,*xTT=xB;
#define gtc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
inline void read(int &sum){
register char ch=gtc();
for(sum=;ch<''||ch>'';ch=gtc());
for(;ch>=''&&ch<='';sum=(sum<<)+(sum<<)+ch-'',ch=gtc());
}
struct Segment_Tree{
Segment_Tree *ch[];
int size;
}node[N*],*add[N],*red[N],*null,*root[N];
int cnt1,cnt2;
int n,cnt;
int val[N];
struct V{
int to,next;
}c[N<<];
int head[N],t,sz;
int ote[N],weight[N],deep[N],size[N];
int Ti,top[N],dfn[N],id[N];
inline void Init(){
null=newnode;
null->ch[]=null->ch[]=null;
null->size=;
for(int i=;i<=n;++i)root[i]=null;
}
inline void U1(Segment_Tree *&p,int l,int r,int pos){
--p->size;
if(l==r)return;
if(pos<=mid)U1(p->ch[],l,mid,pos);
else U1(p->ch[],mid+,r,pos);
}
inline void U2(Segment_Tree *&p,int l,int r,int pos){
if(p==null)p=newnode,p->ch[]=p->ch[]=null,p->size=;
++p->size;
if(l==r)return;
if(pos<=mid)U2(p->ch[],l,mid,pos);
else U2(p->ch[],mid+,r,pos);
}
inline int Q(int l,int r,int k){
if(l==r)return l;
register int sum=,i;
for(i=;i<=cnt1;++i)
sum+=add[i]->ch[]->size;
for(i=;i<=cnt2;++i)
sum-=red[i]->ch[]->size;
if(sum>=k){
for(i=;i<=cnt1;++i)
add[i]=add[i]->ch[];
for(i=;i<=cnt2;++i)
red[i]=red[i]->ch[];
return Q(mid+,r,k);
}else{
for(i=;i<=cnt1;++i)
add[i]=add[i]->ch[];
for(i=;i<=cnt2;++i)
red[i]=red[i]->ch[];
return Q(l,mid,k-sum);
}
}
inline void Q1(int pos){
for(;pos>;pos-=pos&(-pos))
add[++cnt1]=root[pos],cnt+=root[pos]->size;
}
inline void Q2(int pos){
for(;pos>;pos-=pos&(-pos))
red[++cnt2]=root[pos],cnt-=root[pos]->size;
}
inline void U(int pos,int val0,int val){
for(;pos<=n;pos+=pos&(-pos))
U1(root[pos],,Inf,val0),U2(root[pos],,Inf,val);
}
inline void U(int pos,int val){
for(;pos<=n;pos+=pos&(-pos))
U2(root[pos],,Inf,val);
}
inline void addedge(int x,int y){
c[++t].to=y,c[t].next=head[x],head[x]=t;
}
inline void dfs1(int x,int OPai){
ote[x]=OPai,deep[x]=deep[OPai]+;
size[x]=;
for(int i=head[x];i;i=c[i].next)
if(c[i].to!=OPai){
dfs1(c[i].to,x);
size[x]+=size[c[i].to];
if(size[c[i].to]>size[weight[x]])
weight[x]=c[i].to;
}
}
inline void dfs2(int x,int tp){
dfn[x]=++Ti,id[Ti]=x,top[x]=tp;
if(weight[x]==)return;
dfs2(weight[x],tp);
for(int i=head[x];i;i=c[i].next)
if(c[i].to!=ote[x]&&c[i].to!=weight[x])
dfs2(c[i].to,c[i].to);
}
inline void Q(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])std::swap(x,y);
Q1(dfn[x]),Q2(dfn[top[x]]-);
x=ote[top[x]];
}
if(deep[x]<deep[y])std::swap(x,y);
Q1(dfn[x]),Q2(dfn[y]-);
}
int main(){
int T;
read(n),read(T),Init();
for(int i=;i<=n;++i)read(val[i]);
for(int i=,x,y;i<n;++i){
read(x),read(y);
addedge(x,y),addedge(y,x);
}
dfs1(,),dfs2(,);
for(int i=;i<=n;++i)
U(dfn[i],val[i]);
int k,a,b;
while(T--){
read(k),read(a),read(b);
if(k==){
U(dfn[a],val[a],b),val[a]=b;
continue;
}
cnt1=cnt2=;
cnt=,Q(a,b);
if(cnt<k){
puts("invalid request!");
continue;
}
printf("%d\n",Q(,Inf,k));
}return ;
}
【BZOJ 1146】[CTSC2008]网络管理Network的更多相关文章
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 870 Solved: 299[Submit] ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
- bzoj 1146 [CTSC2008]网络管理Network
很久之前写过 count on the tree. 然后一直不懂树状数组是怎么套上这个主席树的. 看了两小时发现它套的就是个权值线段树, 看不出来可持久化在哪里. 因为动态开点所以空间nlog2n. ...
- BZOJ 1146: [CTSC2008]网络管理Network 带修改主席树_树套树_DFS序
Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路 ...
- [BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
- 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理
令人抓狂的整体二分题.根本原因还是我太菜了. 在学校写了一个下午写得头晕,回家里重写了一遍,一个小时就写完了--不过还是太慢. 题目传送门:洛谷P4175. 题意简述: 一棵 \(n\) 个结点的树, ...
- [BZOJ1146][CTSC2008]网络管理Network
[BZOJ1146][CTSC2008]网络管理Network 试题描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建 ...
- Luogu4175:[CTSC2008]网络管理Network
题面 Luogu4175:[CTSC2008]网络管理Network Sol 路径第\(k\)大 无解直接判断就好了 然后整体二分,加上树链剖分+树状数组统计 # include <bits/s ...
随机推荐
- thinkphp-PHP实现pdf导出功能
Thinkphp框架引用tcpdf插件,插件下载地址:待续... 代码编写前先引入tcpdf整个文件夹到项目目录的ThinkPHP文件夹下 如:/ThinkPHP/Library/Vendor/tcp ...
- PHP----composer安装和TP5验证码类
妈的,想用TP5做个项目,用到登录验证码了,结果煞笔TP5不内置了,需要用Composer,用吧,来下载 1.安装Composer 1.1 更新 sudo apt-get update 1.2 安装w ...
- 右键添加git-bash
主要: 右键如果没有git-bash,如何给右键手动添加 前面对右键存在git-bash但使用出现问题的解决,也想到如果右键都没有,该如何给右键添加了,于是接着记录下如何添加的过程: 情形: 手动给右 ...
- ARM串口控制终端命令
配置开发板eth0网络: # ifconfig eth0 10.70.12.168
- UVA 1593 Alignment of Code(紫书习题5-1 字符串流)
You are working in a team that writes Incredibly Customizable Programming Codewriter (ICPC) which is ...
- MVC中路由的修改和浏览器的地址参数
在 ASP.NET MVC 应用程序中,它是更常见的做法在作为路由数据 (像我们一样与身份证上面) 比将它们作为查询字符串传递的参数中传递. ) { return HttpUtility.HtmlEn ...
- DecimalFormat的用法
DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字. DecimalFormat 包含一个模式 和一组符符号含义: 0 一个数字 # 一个数字,不包括 0 ...
- http报文和浏览器缓存机制
目录 1. 请求报文 1.1请求行 1.2 请求头 一些常用的请求头信息 2. 响应报文 2.1 状态行 1> 响应状态码 2> 常见的响应状态码 2.2 响应头 3. 浏览器缓存 3.1 ...
- android中接入twitter进行第三方登录
在应用中接入Twitter进行第三方登录时,开发人员遇到了一点问题,主要是概念有点混乱,这里把经验记录一下,帮助遇到同样问题的朋友. 一.注册应用并配置登录权限 这一步比较简单,就不多说了,直接去官网 ...
- iOS笔记054 - 核心动画
注意事项 :locationInView和translationInView // 返回相对于控件自身内部触摸点的位置 [pan locationInView:self]; // 返回两个触摸点之间的 ...