[CTSC2008]网络管理(整体二分+树剖+树状数组)
一道经典的带修改树链第 \(k\) 大的问题。
我只想出三个 \(\log\) 的解法。。。
整体二分+树剖+树状数组。
那不是暴力随便踩的吗???
不过跑得挺快的。
\(Code\ Below:\)
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int maxn=80000+10;
const int lim=1e8;
int n,m,a[maxn],c[maxn],ans[maxn],cnt,num;
int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn],id[maxn],tim;
int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
struct Query{
int op,x,y,k,id;
}q[maxn*3],q1[maxn*3],q2[maxn*3];
inline int read(){
register int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return (f==1)?x:-x;
}
inline void update(int x,int y){
for(;x<=n;x+=lowbit(x)) c[x]+=y;
}
inline int sum(int x){
int ans=0;
for(;x;x-=lowbit(x)) ans+=c[x];
return ans;
}
inline void clear(int x){
for(;x<=n;x+=lowbit(x)){
if(c[x]) c[x]=0;
else break;
}
}
inline void addedge(int x,int y){
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs1(int x,int f){
siz[x]=1;fa[x]=f;
dep[x]=dep[f]+1;
int maxson=-1;
for(int i=head[x],y;i;i=nxt[i]){
y=to[i];
if(y==f) continue;
dfs1(y,x);siz[x]+=siz[y];
if(siz[y]>maxson) maxson=siz[y],son[x]=y;
}
}
void dfs2(int x,int topf){
top[x]=topf;id[x]=++tim;
if(son[x]) dfs2(son[x],topf);
for(int i=head[x],y;i;i=nxt[i]){
y=to[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
inline int query(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=sum(id[x])-sum(id[top[x]]-1);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=sum(id[y])-sum(id[x]-1);
return ans;
}
void solve(int L,int R,int l,int r){
if(L>R) return ;
if(l==r){
for(int i=L;i<=R;i++){
if(q[i].op==1) update(q[i].x,q[i].k);
else {
if(q[i].k<=query(q[i].x,q[i].y)) ans[q[i].id]=l;
else ans[q[i].id]=-1;
}
}
for(int i=L;i<=R;i++)
if(q[i].op==1) clear(q[i].x);
return ;
}
int mid=(l+r)>>1,cnt1=0,cnt2=0,val;
for(int i=L;i<=R;i++){
if(q[i].op==1){
if(q[i].y<=mid) q1[++cnt1]=q[i];
else update(q[i].x,q[i].k),q2[++cnt2]=q[i];
}
else {
val=query(q[i].x,q[i].y);
if(q[i].k>val) q[i].k-=val,q1[++cnt1]=q[i];
else q2[++cnt2]=q[i];
}
}
for(int i=L;i<=R;i++)
if(q[i].op==1&&q[i].y>mid) clear(q[i].x);
for(int i=1;i<=cnt1;i++) q[L+i-1]=q1[i];
for(int i=1;i<=cnt2;i++) q[L+cnt1+i-1]=q2[i];
solve(L,L+cnt1-1,l,mid);solve(L+cnt1,R,mid+1,r);
}
int main()
{
n=read(),m=read();
int k,x,y;
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<n;i++){
x=read(),y=read();
addedge(x,y);addedge(y,x);
}
dfs1(1,0);dfs2(1,1);
for(int i=1;i<=n;i++) q[++cnt]=(Query){1,id[i],a[i],1,0};
while(m--){
k=read(),x=read(),y=read();
if(k==0){
q[++cnt]=(Query){1,id[x],a[x],-1,0};
q[++cnt]=(Query){1,id[x],y,1,0};
a[x]=y;
}
else {
q[++cnt]=(Query){2,x,y,k,++num};
}
}
solve(1,cnt,0,lim);
for(int i=1;i<=num;i++){
if(ans[i]==-1) printf("invalid request!\n");
else printf("%d\n",ans[i]);
}
return 0;
}
[CTSC2008]网络管理(整体二分+树剖+树状数组)的更多相关文章
- [CTSC2008]网络管理 [整体二分]
题面 bzoj luogu 所有事件按时间排序 按值划分下放 把每一个修改 改成一个删除一个插入 对于一个查询 直接查这个段区间有多少合法点 如果查询值大于等于目标值 进入左区间 如果一个查询无解 那 ...
- [BZOJ2738]矩阵乘法(整体二分+二维树状数组)
整体二分+二维树状数组. 好题啊!写了一个来小时. 一看这道题,主席树不会搞,只能用离线的做法了. 整体二分真是个好东西,啥都可以搞,尤其是区间第 \(k\) 大这种东西. 我们二分答案,然后用二维树 ...
- 【bzoj2738】矩阵乘法 整体二分+二维树状数组
题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5个数 ...
- P3250 [HNOI2016] 网络 (树剖+堆/整体二分+树上差分+树状数组)
解法1: 本题有插入路径和删除路径,在每个节点维护插入堆和删除堆,查询时两者top一样则一直弹出.如果每个节点维护的是经过他的路径,显然有些不好处理,正难则反,每个点维护不经过他的路径,那么x节点出了 ...
- BZOJ2738矩阵乘法——整体二分+二维树状数组
题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入 第一行两个数N,Q,表示矩阵大小和询问组数:接下来N行N列一共N*N个数,表示这个矩阵:再接下来Q行每行5 ...
- luogu3250 网络 (整体二分+树上差分+树状数组)
首先整体二分,问题变成是否存在经过一个点的满足条件的路径 那么我对于每个路径(a,b,lca),在树状数组的dfn[a]++,dfn[b]++,dfn[lca]--,dfn[fa[lca]--] 然后 ...
- BZOJ.2738.矩阵乘法(整体二分 二维树状数组)
题目链接 BZOJ 洛谷 整体二分.把求序列第K小的树状数组改成二维树状数组就行了. 初始答案区间有点大,离散化一下. 因为这题是一开始给点,之后询问,so可以先处理该区间值在l~mid的修改,再处理 ...
- BZOJ 2738 矩阵乘法(整体二分+二维树状数组)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2738 [题目大意] 给出一个方格图,询问要求求出矩阵内第k小的元素 [题解] 我们对答 ...
- 【清澄A1333】【整体二分+二维树状数组】矩阵乘法(梁盾)
试题来源 2012中国国家集训队命题答辩 问题描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入格式 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共 ...
随机推荐
- 技术课堂】如何管理MongoDB数据库?
- 网络编程之IO模型
IO模型的分类 blocking IO:阻塞IO nonblocking IO:非阻塞IO IO multiplexing:IO多路复用 signal driven IO:异步IO 通常情况下IO默认 ...
- 720. Longest Word in Dictionary
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...
- 2019.01.17 bzoj1853: [Scoi2010]幸运数字(容斥+dfs)
传送门 搜索菜题,然而第一次没有注意然后爆longlonglong longlonglong了. 题意:称所有数位由6,86,86,8组成的数为幸运数字,问一个一个区间[l,r][l,r][l,r]中 ...
- 2018.11.03 NOIP模拟 图(bfs/最短路)
传送门 显然如果AAA到BBB或者CCC到DDD走的不是最短路一定是有一段路径重合了,于是可以O(n2)bfsO(n^2)bfsO(n2)bfs出两点之间的最短距离然后枚举两个点作为重合的端点来更新答 ...
- ubuntu卸载软件命令,apt-get remove
第一步,apt-get remove xxx :就是卸载xxx 或者 apt-get remove --purge xxx :卸载xxx并清除配置. 这两条命令对于依赖则是不管的.因为别的软件可 ...
- linux上搭建solr(用jetty部署)
环境搭建:centos7及solr7版本 描述:最新版本的solr内置了jetty容器,可以支持jetty部署,从而不需要发布到tomcat下面 首先同样先在/usr/local/mypackage上 ...
- MIT molecular Biology 笔记8 RNA剪接
视频 https://www.bilibili.com/video/av7973580/ 教材 Molecular biology of the gene 7th edition J.D. Wat ...
- 关于latex的网站推荐
有时候,你不知道某个数学符号的tex写法是什么,可以在下面这个网站手写该符号,然后会出现很多候选. http://detexify.kirelabs.org/classify.html 用latex处 ...
- limit
在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. SELECT * FROM table LIMIT [offset ...