【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 ...
随机推荐
- mysql 常用函数,基本使用
1:选中排除表1 连接表2 表3 获取选中表1中部分选中表3 的部分 并且设置选中状态select t1.*,if(t2中t3id=t1.id,1,0)as checked from t1 lefet ...
- Hadoop(25)-高可用集群配置,HDFS-HA和YARN-HA
一. HA概述 1. 所谓HA(High Available),即高可用(7*24小时不中断服务). 2. 实现高可用最关键的策略是消除单点故障.HA严格来说应该分成各个组件的HA机制:HDFS的HA ...
- eclipse全选包
按住shift键,点击第一个jar包,然后点击最后一个jar包,就全选了所有jar包,然后添加build path 添加到类路径
- crest value &minimum
public class paixu { public static void main(String[] args) { double temp; double num[]={5.1, 7.12, ...
- 算法竞赛入门经典-1.5.4 Q&A
这小节考察实践能力,要求在不要查书.不要网上找答案,自己用实验的方法解决以下五个问题: 做这五道题时,好几道都没思路,违反了规则到网上找了一圈,居然没找到答案,于是打算写这篇博客.不知是否有更好的实践 ...
- python入门——Anaconda安装
初学Python,可以选择python原始的IDE,但原始的IDE在使用过程中需要自己安装各种包,个人觉得初学者不需要将时间花在这些上面,而是应该直接学习python程序,这些比较杂的事情可以在以后的 ...
- C++11中std::forward的使用
std::forward argument: Returns an rvalue reference to arg if arg is not an lvalue reference; If arg ...
- Mysql双主操作
MySQL双主(主主)架构方案 在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动.因此,如果 ...
- 深入浅出 Webpack
深入浅出 Webpack 评价 Webpack 凭借强大的功能与良好的使用体验,已经成为目前最流行,社区最活跃的打包工具,是现代 Web 开发必须掌握的技能之一.作者结合自身的实战经验,介绍了 Web ...
- mysql 导入CSV数据 [转]
转自: http://blog.chinaunix.net/uid-23284114-id-3196638.html MYSQL LOAD DATA INFILE命令可以把csv平面文件中的数据导 ...