洛谷P4175 - [CTSC2008]网络管理
Description
给出一棵\(n(n\leq8\times10^4)\)个点的带点权的树,进行\(m(m\leq8\times10^4)\)次操作,操作有两种:
- 修改一个点的点权。
- 询问路径\((u,v)\)上第\(k\)大的点权。若路径上的点不足\(k\)个输出
invalid request!。
Solution
带修改的可持久化线段树。
首先对于每个节点\(u\)建立一棵线段树记录路径\((u,rt)\)上的权值分布。考虑修改一个点的权值对这些线段树有什么影响。当\(u\)的权值由\(val\)变为\(val'\)后,子树\(u\)中的所有点的线段树中都有\(cnt[val]-1,cnt[val']+1\)。
对每个点再建立一棵线段树记录修改。修改子树在DFS序上相当于修改区间,差分后变为两个单点修改。于是我们要对于这些线段树进行单点修改,前缀查询;而这可以用树状数组实现。于是我们按DFS序建立树状数组套线段树就可以维护修改带来的影响。当我们需要求路径\((u,rt)\)上的权值分布时,用原线段树加上修改线段树即可。
时间复杂度\(O(mlog^3n)\)。
Code
//[CTSC2008]网络管理
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
inline char gc()
{
static char now[1<<16],*s,*t;
if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
return *s++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
const int N=8e4+10;
int n,m,w[N];
struct optR{int k,u,v;} seq[N];
int wCnt,map[N<<1];
void discrete()
{
int cnt=0;
for(int i=1;i<=n;i++) map[++cnt]=w[i];
for(int i=1;i<=m;i++) if(seq[i].k==0) map[++cnt]=seq[i].v;
sort(map+1,map+cnt+1); wCnt=unique(map+1,map+cnt+1)-map-1;
for(int i=1;i<=n;i++) w[i]=lower_bound(map+1,map+wCnt+1,w[i])-map;
for(int i=1;i<=m;i++) if(seq[i].k==0) seq[i].v=lower_bound(map+1,map+wCnt+1,seq[i].v)-map;
}
const int N1=2e7;
int ndCnt,rt1[N],rt2[N],ch[N1][2],sum[N1];
void trAdd(int t,int x,int v);
int trSum(int t,int L,int R);
void ndCopy(int p,int q) {ch[q][0]=ch[p][0],ch[q][1]=ch[p][1],sum[q]=sum[p];}
void ins1(int &p,int L0,int R0,int x)
{
ndCopy(p,++ndCnt); sum[p=ndCnt]++;
if(L0==R0) return;
int mid=L0+R0>>1;
if(x<=mid) ins1(ch[p][0],L0,mid,x);
else ins1(ch[p][1],mid+1,R0,x);
}
int t1,t2,t3,t4;
int query1(int p1,int p2,int p3,int p4,int L0,int R0,int k)
{
if(L0==R0) return map[L0];
int mid=L0+R0>>1,sumL=0;
sumL+=sum[ch[p1][0]]+trSum(t1,L0,mid)+sum[ch[p2][0]]+trSum(t2,L0,mid);
sumL-=sum[ch[p3][0]]+trSum(t3,L0,mid)+sum[ch[p4][0]]+trSum(t4,L0,mid);
if(sumL>=k) return query1(ch[p1][0],ch[p2][0],ch[p3][0],ch[p4][0],L0,mid,k);
else return query1(ch[p1][1],ch[p2][1],ch[p3][1],ch[p4][1],mid+1,R0,k-sumL);
}
void ins2(int &p,int L0,int R0,int x,int v)
{
if(!p) p=++ndCnt; sum[p]+=v;
if(L0==R0) return;
int mid=L0+R0>>1;
if(x<=mid) ins2(ch[p][0],L0,mid,x,v);
else ins2(ch[p][1],mid+1,R0,x,v);
}
int query2(int p,int L0,int R0,int optL,int optR)
{
if(optL<=L0&&R0<=optR) return sum[p];
int mid=L0+R0>>1,r=0;
if(optL<=mid) r+=query2(ch[p][0],L0,mid,optL,optR);
if(mid<optR) r+=query2(ch[p][1],mid+1,R0,optL,optR);
return r;
}
void trAdd(int t,int x,int v) {while(t<=n) ins2(rt2[t],1,wCnt,x,v),t+=t&(-t);}
int trSum(int t,int L,int R)
{
int r=0;
while(t) r+=query2(rt2[t],1,wCnt,L,R),t-=t&(-t);
return r;
}
vector<int> ed[N];
void edAdd(int u,int v) {ed[u].push_back(v),ed[v].push_back(u);}
int fa[N][20],dpt[N]; int dfCnt,fr[N],to[N];
void dfs(int u)
{
fr[u]=++dfCnt;
ins1(rt1[u]=rt1[fa[u][0]],1,wCnt,w[u]);
for(int k=1;fa[u][k-1];k++) fa[u][k]=fa[fa[u][k-1]][k-1];
for(int i=0;i<ed[u].size();i++)
{
int v=ed[u][i];
if(v==fa[u][0]) continue;
fa[v][0]=u,dpt[v]=dpt[u]+1;
dfs(v);
}
to[u]=dfCnt;
}
int lca(int u,int v)
{
if(dpt[u]<dpt[v]) swap(u,v);
for(int k=17;k>=0;k--) if(dpt[fa[u][k]]>=dpt[v]) u=fa[u][k];
if(u==v) return u;
for(int k=17;k>=0;k--) if(fa[u][k]!=fa[v][k]) u=fa[u][k],v=fa[v][k];
return fa[u][0];
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++) w[i]=read();
for(int i=1;i<=n-1;i++) edAdd(read(),read());
for(int i=1;i<=m;i++) seq[i].k=read(),seq[i].u=read(),seq[i].v=read();
discrete();
dpt[1]=1,dfs(1);
for(int i=1;i<=m;i++)
{
int k=seq[i].k,u=seq[i].u,v=seq[i].v;
if(k==0)
{
trAdd(fr[u],w[u],-1),trAdd(to[u]+1,w[u],1);
w[u]=v; trAdd(fr[u],v,1),trAdd(to[u]+1,v,-1);
}
else
{
int u1=lca(u,v),v1=fa[u1][0],sum1=0;
t1=fr[u],t2=fr[v],t3=fr[u1],t4=fr[v1];
sum1+=sum[rt1[u]]+trSum(t1,1,wCnt)+sum[rt1[v]]+trSum(t2,1,wCnt);
sum1-=sum[rt1[u1]]+trSum(t3,1,wCnt)+sum[rt1[v1]]+trSum(t4,1,wCnt);
if(sum1<k) puts("invalid request!");
else printf("%d\n",query1(rt1[u],rt1[v],rt1[u1],rt1[v1],1,wCnt,sum1-k+1));
}
}
return 0;
}
P.S.
姑且是把之前鸽了的题解都补完了...
洛谷P4175 - [CTSC2008]网络管理的更多相关文章
- 洛谷 P4175 [CTSC2008]网络管理 解题报告
P4175 [CTSC2008]网络管理 题目描述 带修改树上链的第\(k\)大 输入输出格式 输入格式: 第一行为两个整数\(N\)和\(Q\),分别表示路由器总数和询问的总数. 第二行有\(N\) ...
- 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理
令人抓狂的整体二分题.根本原因还是我太菜了. 在学校写了一个下午写得头晕,回家里重写了一遍,一个小时就写完了--不过还是太慢. 题目传送门:洛谷P4175. 题意简述: 一棵 \(n\) 个结点的树, ...
- 洛谷P4175 网络管理
题意:链上带修第k大. 这毒瘤题...别看题意只有7个字,能把我吊打死... 介绍其中两种做法好了.其实思想上是一样的. 对于每一个点,建立权值线段树,维护它到根路径上的所有权值. 一条路径上的点集就 ...
- P4175 [CTSC2008]网络管理
如果没有修改就是简单主席树,有了修改的话因为主席树维护的是到根的一段路径,所以修改操作会修改子树,也就是连续的一段dfn 所以显然树套树一波就没了 极其好写 #include<bits/stdc ...
- P4175 [CTSC2008]网络管理 树剖+树套树
$ \color{#0066ff}{ 题目描述 }$ M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通 ...
- 洛谷 P4298: bzoj 1143: [CTSC2008]祭祀
题目传送门:洛谷 P4298. 题意简述: 给定一个 \(n\) 个点,\(m\) 条边的简单有向无环图(DAG),求出它的最长反链,并构造方案. 最长反链:一张有向无环图的最长反链为一个集合 \(S ...
- 【LG4175】[CTSC2008]网络管理
[LG4175][CTSC2008]网络管理 题面 洛谷 题解 感觉就和普通的整体二分差不太多啊... 树上修改就按时间添加,用树状数组维护一下即可 代码 #include<iostream&g ...
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
随机推荐
- 2018.5.11 Java利用反射实现对象克隆
package com.lanqiao.demo; /** * 创建人 * @author qichunlin * */ public class Person { private int id; p ...
- 2018.4.15 Mac系统下如何使用StartUml画好需求分析的类图 (同样适用于windows)
Mac如何使用StartUml (同样适用于windows) 左侧边栏的英文含义及其用法 关联(Association) [关联关系]:是一种拥有的关系,它使一个类知道另一个类的属性和方法:如:老师与 ...
- python3从尾到头打印链表
题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 方法一:通过栈实现 # -*- coding:utf-8 -*- # class ListNode: # def __ini ...
- k8s1.13.0二进制部署-node节点(四)
Master apiserver启用TLS认证后,Node节点kubelet组件想要加入集群,必须使用CA签发的有效证书才能与apiserver通信,当Node节点很多时,签署证书是一件很繁琐的事情, ...
- c#和Java中的接口
使用场景: 在c#和Java中: 1.接口可以实现“多继承”(多实现),一个类只能继承自一个父类,但是可以实现多个接口. 2.接口解决了不同类型之间的多态问题,比如鱼与船不是同一类型,但是都能在水里“ ...
- mysql中添加数据时,报错(incorrect string value:'\xf0\x9f ) 字符转换不正确
这个问题,原因是UTF-8编码有可能是两个.三个.四个字节.Emoji表情或者某些特殊字符是4个字节,而Mysql的utf8编码最多3个字节,所以数据插不进去. 在网上搜了一下解决问题的方案,我选了一 ...
- HTML5<section>元素
HTML5<section>元素用来定义页面文档中的逻辑区域或内容的整合(section,区域),比如章节.页眉.页脚或文档中的其他部分. 根据W3C HTML5文档中:section里面 ...
- VueX源码分析(4)
VueX源码分析(4) /module store.js /module/module.js import { forEachValue } from '../util' // Base data s ...
- 【SAM】bzoj5084: hashit
做得心 力 憔 悴 Description 你有一个字符串S,一开始为空串,要求支持两种操作 在S后面加入字母C 删除S最后一个字母 问每次操作后S有多少个两两不同的连续子串 Input 一行一个字符 ...
- Linux基础学习-网络管理
Linux系统网络管理NetworkManager 1 启动网络管理服务和开机自启动 在rhel7中网路管理相关命令nmcli,nmtui,nmtui-edit,nm-connection-edito ...