BZOJ 1146: [CTSC2008]网络管理Network 带修改主席树_树套树_DFS序
Description
Input
Output
题解:
树套树.
之前做过不带修改的,感觉还挺容易的.
这次是带修改版本,就不能直接在树上建主席树了.
不同的是,我们对 $DFS$ 序建立主席树
考虑到每一次修改一个点,只会对该点的子树到根的路径产生影响.
在 DFS 序中,每个点的子树是一段连续的区间,直接用带修改主席树修改一波即可.
在 DFS 序中,每个点到根节点的路径和就是该点在 DFS 序中的前缀和.
这样进行修改和查询即可.
Code:
#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout)
#define maxn 200000
#define N 180000
using namespace std;
int n,q, edges,cc,num;
//权值线段树
namespace Seg
{
#define mid ((l+r)>>1)
int rt[maxn],node[10][maxn],cnt[10];
int tot;
struct Node
{
int l,r,w;
}t[maxn*50];
void insert(int &x,int l,int r,int k,int delta)
{
if(!x) x=++tot;
t[x].w+=delta;
if(l==r) return;
if(k<=mid)
insert(t[x].l,l,mid,k,delta);
else
insert(t[x].r,mid+1,r,k,delta);
}
int lowbit(int t)
{
return t & (-t);
}
void update(int pos,int val,int delta)
{
while(pos<=N) insert(rt[pos],1,N,val,delta),pos+=lowbit(pos);
}
int query(int l,int r,int kth)
{
if(l==r) return l;
int sum=0;
for(int i=1;i<=cnt[0];++i) sum+=t[t[node[0][i]].r].w;
for(int i=1;i<=cnt[1];++i) sum+=t[t[node[1][i]].r].w;
for(int i=1;i<=cnt[2];++i) sum-=t[t[node[2][i]].r].w;
for(int i=1;i<=cnt[3];++i) sum-=t[t[node[3][i]].r].w;
if(sum < kth)
{
for(int i=1;i<=cnt[0];++i) node[0][i] = t[node[0][i]].l;
for(int i=1;i<=cnt[1];++i) node[1][i] = t[node[1][i]].l;
for(int i=1;i<=cnt[2];++i) node[2][i] = t[node[2][i]].l;
for(int i=1;i<=cnt[3];++i) node[3][i] = t[node[3][i]].l;
return query(l,mid,kth-sum);
}
else
{
for(int i=1;i<=cnt[0];++i) node[0][i] = t[node[0][i]].r;
for(int i=1;i<=cnt[1];++i) node[1][i] = t[node[1][i]].r;
for(int i=1;i<=cnt[2];++i) node[2][i] = t[node[2][i]].r;
for(int i=1;i<=cnt[3];++i) node[3][i] = t[node[3][i]].r;
return query(mid+1,r,kth);
}
}
// 关键字 : 位置
int Query(int a,int b,int c,int d,int kth)
{
cnt[0]=cnt[1]=cnt[2]=cnt[3]=0;
for(int i=a;i>0;i-=lowbit(i)) node[0][++cnt[0]] = rt[i];
for(int i=b;i>0;i-=lowbit(i)) node[1][++cnt[1]] = rt[i];
for(int i=c;i>0;i-=lowbit(i)) node[2][++cnt[2]] = rt[i];
for(int i=d;i>0;i-=lowbit(i)) node[3][++cnt[3]] = rt[i];
return query(1,N,kth);
}
};
struct Query
{
int opt,a,b;
}Q[maxn];
int hd[maxn],to[maxn],nex[maxn],dfs[maxn],arr[maxn],A[maxn];
int st[maxn],ed[maxn],F[20][maxn],dep[maxn],val[maxn];
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
//read and diskreat
void read()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;++i) scanf("%d",&val[i]),A[++cc]=val[i];
for(int i=1,a,b;i<n;++i)
scanf("%d%d",&a,&b), add(a,b),add(b,a);
for(int i=1;i<=q;++i)
{
scanf("%d%d%d",&Q[i].opt,&Q[i].a,&Q[i].b);
if(Q[i].opt==0) A[++cc]=Q[i].b;
}
sort(A+1,A+1+cc);
for(int i=1;i<=q;++i) if(Q[i].opt==0) Q[i].b=lower_bound(A+1,A+1+cc,Q[i].b)-A;
for(int i=1;i<=n;++i) val[i] = lower_bound(A+1,A+1+cc,val[i])-A;
}
//求dfs序
void DFS(int u,int fa)
{
F[0][u]=fa, dep[u] = dep[fa] + 1;
for(int i=1;i<20;++i) F[i][u]=F[i-1][F[i-1][u]];
dfs[++num]=val[u],st[u]=num;
for(int i=hd[u];i;i=nex[i])
{
if(to[i]==fa) continue;
DFS(to[i],u);
}
ed[u]=num+1;
}
int LCA(int a,int b)
{
if(dep[b]<dep[a]) swap(a,b);
if(dep[a]!=dep[b])
{
for(int i=19;i>=0;--i) if(dep[F[i][b]] >= dep[a]) b = F[i][b];
}
if(a==b) return a;
for(int i=19;i>=0;--i)
{
if(F[i][a]!=F[i][b]) a = F[i][a], b = F[i][b];
}
return F[0][a];
}
int main()
{
// setIO("input");
read();
DFS(1,0);
for(int i = 1;i <= n; ++i)
{
Seg::update(st[i],val[i], 1);
Seg::update(ed[i],val[i], -1);
}
for(int i=1,a,b;i<=q;++i)
{
a = Q[i].a, b = Q[i].b;
if(Q[i].opt==0)
{
Seg::update(st[a], val[a], -1);
Seg::update(ed[a], val[a], 1);
val[a] = b;
Seg::update(st[a],val[a], 1);
Seg::update(ed[a],val[a], -1);
}
if(Q[i].opt>0)
{
int lca = LCA(a,b);
int c = Seg::Query(st[a],st[b],st[lca],st[F[0][lca]],Q[i].opt);
if(c==1)
printf("invalid request!\n");
else
printf("%d\n",A[c]);
}
}
return 0;
}
BZOJ 1146: [CTSC2008]网络管理Network 带修改主席树_树套树_DFS序的更多相关文章
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 870 Solved: 299[Submit] ...
- [BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- bzoj 1146 [CTSC2008]网络管理Network
很久之前写过 count on the tree. 然后一直不懂树状数组是怎么套上这个主席树的. 看了两小时发现它套的就是个权值线段树, 看不出来可持久化在哪里. 因为动态开点所以空间nlog2n. ...
- BZOJ 1901: Zju2112 Dynamic Rankings | 带修改主席树
题目: emmmm是个权限题 题解: 带修改主席树的板子题,核心思想是用树状数组维护动态前缀和的性质来支持修改 修改的时候修改类似树状数组一样进行logn个Insert 查询的时候同理,树状数组的方法 ...
- 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理
令人抓狂的整体二分题.根本原因还是我太菜了. 在学校写了一个下午写得头晕,回家里重写了一遍,一个小时就写完了--不过还是太慢. 题目传送门:洛谷P4175. 题意简述: 一棵 \(n\) 个结点的树, ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
- 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树
[BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...
随机推荐
- CI笔记
1.控制器 实现自己的控制器MY_Controller是在./application/core/MY_Controller.php中. 2.类库 添加自己的类是放在./application./lib ...
- C - 剪花布条
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input输入中含有一些数据,分别是成对出现的花布条和 ...
- 洛谷 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows
P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 题目描述 Each of Farmer John's N (4 <= N <= 16) cows has a u ...
- ddl in PL/SQL
If you write DDL directly in PL/SQL. You will hit error. 1 DECLARE 2 str_sql varchar2(500); 3 begin ...
- 怎样使用ListView实现一个带有网络请求,解析,分页,缓存的公共的List页面来大大的提高工作效率
在寻常的开发中常常会有非常多列表页面.每做一个列表页就须要创建这个布局文件那个Adapter适配器文件等等一大堆与之相关的附属的不必要的冗余文件. 假设版本号更新迭代比較频繁,如此以往,就会使项目pr ...
- codeforces #262 DIV2 B题 Little Dima and Equation
题目地址:http://codeforces.com/contest/460/problem/B 这题乍一看没思路.可是细致分析下会发现,s(x)是一个从1到81的数,不管x是多少.所以能够枚举1到8 ...
- CSS3 网格布局(grid layout)基础知识 - 隐式网格自己主动布局(grid-auto-rows/grid-auto-columns/grid-auto-flow)
网格模板(grid-template)属性及其普通写法(longhands)定义了一个固定数量的轨道.构成显式网格. 当网格项目定位在这些界限之外.网格容器通过添加隐式网格线生成隐式网格轨道. 这些隐 ...
- Java获取路径中的文件名(正则表达式)
Java获取路径中的文件名(正则表达式) 目标 在这个路径中我想得到model2 /E:/2017-02-21--SoftWare/github/test/Java/poiDemo_word2exce ...
- 2017 Multi-University Training Contest - Team 2 &&hdu 6050 Funny Function
Funny Function Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 【POJ 3322】 Bloxorz I
[题目链接] http://poj.org/problem?id=3322 [算法] 广度优先搜索 [代码] #include <algorithm> #include <bitse ...