【BZOJ1146】网络管理(整体二分)
【BZOJ1146】网络管理(整体二分)
题面
题解
要看树套树的戳这里
毕竟是:智商不够数据结构来补
所以,
我们来当一回智商够的选手
听说主席树的题目大部分都可以整体二分
这题丢进去整体二分就行了
只需要查询树上贡献的前缀和
但是,对于这种带修改的
不能够直接修改
每一个修改操作必须拆成两个:
一个删掉原来的修改,一个加入现在的修改
否则就会重复计算贡献从而\(gg\)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 81000
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int dfn[MAX],low[MAX],fa[MAX],size[MAX],hson[MAX],dep[MAX],top[MAX];
int tim,n,Q;
int LCA(int u,int v)
{
while(top[u]!=top[v])
dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];
return dep[u]<dep[v]?u:v;
}
void dfs1(int u,int ff)
{
size[u]=1;fa[u]=ff;dep[u]=dep[ff]+1;
for(int i=h[u];i;i=e[i].next)
{
if(e[i].v==ff)continue;
dfs1(e[i].v,u);
size[u]+=size[e[i].v];
if(size[e[i].v]>size[hson[u]])hson[u]=e[i].v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;dfn[u]=++tim;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
{
if(e[i].v==fa[u]||e[i].v==hson[u])continue;
dfs2(e[i].v,e[i].v);
}
low[u]=tim;
}
int sum,ans[MAX];
struct Op{int k,a,b,id,opt;}O[MAX<<1],p1[MAX<<1],p2[MAX<<1];
int c[MAX],TT[MAX];
int lowbit(int x){return x&(-x);}
void add(int x,int w){while(x<=n)c[x]+=w,x+=lowbit(x);}
int getsum(int x){int ret=0;while(x)ret+=c[x],x-=lowbit(x);return ret;}
int jump(int u,int v)
{
int ret=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
ret+=getsum(dfn[u])-getsum(dfn[top[u]]-1);
u=fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
ret+=getsum(dfn[u])-getsum(dfn[v]-1);
return ret;
}
void Work(int L,int R,int l,int r)
{
if(L>R)return;
if(l==r)
{
for(int i=L;i<=R;++i)
if(!O[i].opt&&ans[O[i].id]!=-1)ans[O[i].id]=l;
return;
}
int mid=(l+r)>>1;
int t1=0,t2=0;
for(int i=L;i<=R;++i)
{
if(O[i].k==0)
{
if(O[i].b<=mid)p1[++t1]=O[i];
else p2[++t2]=O[i],add(dfn[O[i].a],O[i].id);
}
else
{
int ss=jump(O[i].a,O[i].b);
if(ss>=O[i].k)p2[++t2]=O[i];
else O[i].k-=ss,p1[++t1]=O[i];
}
}
for(int i=L;i<=R;++i)if(O[i].opt&&O[i].b>mid)add(dfn[O[i].a],-O[i].id);
for(int i=1;i<=t1;++i)O[L+i-1]=p1[i];
for(int i=1;i<=t2;++i)O[L+t1+i-1]=p2[i];
Work(L,L+t1-1,l,mid);Work(L+t1,R,mid+1,r);
}
int main()
{
n=read();Q=read();
int Cnt=0;
for(int i=1;i<=n;++i)
{
TT[i]=read();
O[++Cnt]=(Op){0,i,TT[i],1,1};
}
for(int i=1;i<n;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
dfs1(1,0);dfs2(1,1);
for(int i=1;i<=Q;++i)
{
int k=read(),a=read(),b=read();
if(k)
{
O[++Cnt]=(Op){k,a,b,++sum,0};
int len=dep[O[Cnt].a]+dep[O[Cnt].b]-2*dep[LCA(O[Cnt].a,O[Cnt].b)]+1;
if(O[Cnt].k>len)ans[O[Cnt].id]=-1;
}
else
{
O[++Cnt]=(Op){0,a,TT[a],-1,1};
O[++Cnt]=(Op){0,a,TT[a]=b,1,1};
}
}
Work(1,Cnt,1,1e8);
for(int i=1;i<=sum;++i)
ans[i]!=-1?printf("%d\n",ans[i]):puts("invalid request!");
return 0;
}
【BZOJ1146】网络管理(整体二分)的更多相关文章
- 【BZOJ1146】【CTSC2008】网络管理 [整体二分]
网络管理 Time Limit: 50 Sec Memory Limit: 162 MB[Submit][Status][Discuss] Description M公司是一个非常庞大的跨国公司,在 ...
- [CTSC2008]网络管理 [整体二分]
题面 bzoj luogu 所有事件按时间排序 按值划分下放 把每一个修改 改成一个删除一个插入 对于一个查询 直接查这个段区间有多少合法点 如果查询值大于等于目标值 进入左区间 如果一个查询无解 那 ...
- 2019.01.13 bzoj1146: [CTSC2008]网络管理Network(整体二分+树剖)
传送门 题意简述:给一棵树,支持单点修改,询问路径上两点间第kkk大值. 思路: 读懂题之后立马可以想到序列上带修区间kkk大数的整体二分做法,就是用一个bitbitbit来支持查值. 那么这个题把树 ...
- bzoj1146整体二分+树链剖分+树状数组
其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...
- [CTSC2008]网络管理(整体二分+树剖+树状数组)
一道经典的带修改树链第 \(k\) 大的问题. 我只想出三个 \(\log\) 的解法... 整体二分+树剖+树状数组. 那不是暴力随便踩的吗??? 不过跑得挺快的. \(Code\ Below:\) ...
- bzoj 1146 网络管理Network (CDQ 整体二分 + 树刨)
题目传送门 题意:求树上路径可修改的第k大值是多少. 题解:CDQ整体二分+树刨. 每一个位置上的数都会有一段持续区间 根据CDQ拆的思维,可以将这个数拆成出现的时间点和消失的时间点. 然后通过整体二 ...
- [CTSC2008]网络管理 [树剖+整体二分]
这题的复杂度可以到达惊人的\(\log^4\)据说还能跑过去(差点没吓死我 直接二分+树剖树套树(\(n \log^4 n\)) 一个\(\log\)也不少的4\(\log\) 但是我有个\(\log ...
- Cdq分治整体二分学习记录
这点东西前前后后拖了好几个星期才学会……还是自己太菜啊. Cdq分治的思想是:把问题序列分割成左右两个,先单独处理左边,再处理左边对右边的影响,再单独处理右边.这样可以消去数据结构上的一个log,降低 ...
- 整体二分QAQ
POJ 2104 K-th Number 时空隧道 题意: 给出一个序列,每次查询区间第k小 分析: 整体二分入门题? 代码: #include<algorithm> #include&l ...
随机推荐
- WdatePicker-限制日期选择
场景: 1. 开始时间,和结束时间最大选择今天. 2. 开始时间和结束时间的最大时间间隔为30天. jsp代码: <!-- 时间段 --> <form> <!-- 开始时 ...
- EFCore数据库迁移命令整理
前言 因为现在用.net core 开发新项目,过程中需要经常涉及到数据命令的迁移,今天分别整EFCore 的两种迁移数据库的方式 1 程序包管理器控制台 , Package Manager Con ...
- Wpf DataGridCheckBoxColumn 问题
使用DataGridCheckBoxColumn binding一个布尔属性时,发现无法checkbox无法勾选, 并且HeaderTemplate中的checkbox无法获取到viewmodel的 ...
- 利用Jsonp实现跨域请求,spring MVC+JQuery
1 什么是Jsonp? JSONP(JSON with Padding)是数据格式JSON的一种"使用模式",可以让网页从别的网域要数据.另一个解决这个问题的新方法是跨来源资源共享 ...
- Appium基于Python unittest自动化测试 & 自动化测试框架 -- PO并生成html测试报告
基于python单元测试框架unittest完成appium自动化测试,生成基于html可视化测试报告 代码示例: #利用unittest并生成测试报告 class Appium_test(unitt ...
- [原创]ubuntu14.04部署ELK+redis日志分析系统
ubuntu14.04部署ELK+redis日志分析系统 [环境] host1:172.17.0.4 搭建ELK+redis服务 host2:172.17.0.3 搭建logstash+nginx服务 ...
- 大数相加(类似杭电acm1002)
/*输入两个非常大的整数(完全超出了int.long的表示范围),这个整数的长度可能超过100位,计算并输出这两个数相加的结果.*/ //自己用题目所给的案例测试,输出是正确的,也能输出正确的结果,不 ...
- python介绍篇
二进制编码ASSIC 每一个字符统一都需要8个bit来存储 计算机容量 1位 = 1bit 8bit = 1byte = 1字节 1024bytes = 1kbytes =1KB 1024个字符,小文 ...
- (转)Hanoi塔问题分析
转自:http://shmilyaw-hotmail-com.iteye.com/blog/2077098 简介 关于Hanoi塔问题的分析,在网上的文章都写烂了.之所以打算写这篇文章,更多的是针对这 ...
- 多文件工程的编译-Makefile的简便写法
通常我们在命令行使用GCC对程序进行编译,如果对于单个或者几个文件时比较方便的,但当工程中的文件逐渐增多甚至变得十分庞大的时候,使用GCC显然力不从心,不好管理.因此我们有必要编写一个Makefile ...