[Luogu4175][CTSC2008]网络管理Network
又是权限题qwq
一句话题意:带修改树上路径第k大
sol
数据结构?还是再见吧。学一手合格的整体二分,只有思维强大,才能见题拆题。
如果你做过整体二分的动态区间第k大就会发现这是一样的题。
无非是区间变成了树上路径。
怎么办呢?树剖+dfn序不就好了吗。
复杂度算下来貌似是\(O(n\log^3{n})\)的。
\(O(\mbox{跑得过})\)
code
注意是第k大啊!第k大啊!
写成第k小就爆零了。
神坑样例。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N = 8e4+5;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
struct edge{int to,next;}a[N<<1];
struct node{int opt,x,y,id,k;}q[N<<2],q1[N<<2],q2[N<<2];
int n,m,head[N],cnt,qcnt,T[N],fa[N],dep[N],sz[N],son[N],top[N],dfn[N],tmp[N],c[N],ans[N];
void dfs1(int u,int f)
{
fa[u]=f;dep[u]=dep[f]+1;sz[u]=1;
for (int e=head[u];e;e=a[e].next)
{
int v=a[e].to;if (v==f) continue;
dfs1(v,u);
sz[u]+=sz[v];
if (sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int up)
{
top[u]=up;dfn[u]=++cnt;
if (son[u]) dfs2(son[u],up);
for (int e=head[u];e;e=a[e].next)
if (a[e].to!=fa[u]&&a[e].to!=son[u])
dfs2(a[e].to,a[e].to);
}
void modify(int k,int v){while (k<=n) c[k]+=v,k+=k&-k;}
int query(int k){int s=0;while (k) s+=c[k],k-=k&-k;return s;}
int lca(int x,int y)
{
while (top[x]^top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int calc(int x,int y)
{
int res=0;
while (top[x]^top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res+=query(dfn[x])-query(dfn[top[x]]-1);
x=fa[top[x]];
}
if (dep[x]<dep[y]) swap(x,y);
res+=query(dfn[x])-query(dfn[y]-1);
return res;
}
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].opt==0) ans[q[i].id]=l;
return;
}
int mid=l+r>>1;
for (int i=L;i<=R;i++)
if (q[i].opt==0) tmp[q[i].id]=calc(q[i].x,q[i].y);
else if (q[i].y<=mid) modify(q[i].x,q[i].opt);
for (int i=L;i<=R;i++)
if (q[i].opt!=0&&q[i].y<=mid) modify(q[i].x,-q[i].opt);
int t1=0,t2=0;
for (int i=L;i<=R;i++)
if (q[i].opt==0)
if (q[i].k<=tmp[q[i].id]) q1[++t1]=q[i];
else q[i].k-=tmp[q[i].id],q2[++t2]=q[i];
else
if (q[i].y<=mid) q1[++t1]=q[i];
else q2[++t2]=q[i];
for (int i=L,j=1;j<=t1;i++,j++) q[i]=q1[j];
for (int i=L+t1,j=1;j<=t2;i++,j++) q[i]=q2[j];
solve(L,L+t1-1,l,mid);solve(L+t1,R,mid+1,r);
}
int main()
{
n=gi();m=gi();
for (int i=1;i<=n;i++) T[i]=gi();
for (int i=1,u,v;i<n;i++)
{
u=gi(),v=gi();
a[++cnt]=(edge){v,head[u]};head[u]=cnt;
a[++cnt]=(edge){u,head[v]};head[v]=cnt;
}
dfs1(1,0);cnt=0;dfs2(1,1);cnt=0;
for (int i=1;i<=n;i++)
q[++cnt]=(node){1,dfn[i],T[i]};
while (m--)
{
int k=gi(),x=gi(),y=gi();
if (k)
{
int len=dep[x]+dep[y]-2*dep[lca(x,y)]+1;
if (k>len) k=1e8;else k=len-k+1;
q[++cnt]=(node){0,x,y,++qcnt,k};
}
else
{
q[++cnt]=(node){-1,dfn[x],T[x]};
T[x]=y;
q[++cnt]=(node){1,dfn[x],T[x]};
}
}
solve(1,cnt,0,1e8);
for (int i=1;i<=qcnt;i++)
if (ans[i]==1e8) puts("invalid request!");
else printf("%d\n",ans[i]);
return 0;
}
[Luogu4175][CTSC2008]网络管理Network的更多相关文章
- Luogu4175:[CTSC2008]网络管理Network
题面 Luogu4175:[CTSC2008]网络管理Network Sol 路径第\(k\)大 无解直接判断就好了 然后整体二分,加上树链剖分+树状数组统计 # include <bits/s ...
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
- [BZOJ1146][CTSC2008]网络管理Network
[BZOJ1146][CTSC2008]网络管理Network 试题描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建 ...
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 870 Solved: 299[Submit] ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
- 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树
[BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...
- bzoj 1146 [CTSC2008]网络管理Network
很久之前写过 count on the tree. 然后一直不懂树状数组是怎么套上这个主席树的. 看了两小时发现它套的就是个权值线段树, 看不出来可持久化在哪里. 因为动态开点所以空间nlog2n. ...
- BZOJ1146——[CTSC2008]网络管理Network
1.题目大意:就是在动态的树上路径权值第k大. 2.分析:这个就是树链剖分+树套树 #include <cstdio> #include <cstdlib> #include ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
随机推荐
- maven的安装与配置使用
一 maven的安装 1 在镜像(https://mirrors.tuna.tsinghua.edu.cn/apache/)中下载指定的版本(注意,Maven 版本与IDE版本应保持匹配). 2 ...
- ansible实践2-拷贝文件或目录
ansible testhost -m copy -a "src=/etc/ansible dest=/tmp/ansibletest owner=root group=root mo ...
- eclipse 使 用Ctrl+鼠标左键进入mapper.xml文件的方法
在 >eclipse MarketPlace中下载>Mybatipse 插件安装重启即可完成
- 浅谈PHP答题卡识别(一)
最近期末考试考完了,我们也要放寒假了.于是突发奇想,想用PHP写一个答题卡识别程序.已经实现了一些,现分享给大家. 具体的步骤如下: 上传答题卡=>图片二值化(已实现)=>寻找定位点(已实 ...
- linux 下安装php curl扩展
方法一 安装cURL wget https://curl.haxx.se/download/curl-7.53.1.tar.gz tar -zxf curl-7.17.1.tar.gz ./confi ...
- maven中的profile文件的解析
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- Egret学习笔记 (Egret打飞机-8.敌机和主角飞机发射子弹)
经过前面几章的准备,我们差不多已经具备了一个基本的框架,这一章我们就开始添砖加瓦了. 敌机定时发射一个子弹,子弹的方向是从上到下,但是发射子弹的代码应该放在哪儿呢? 从面向对象编程的思想来说,子弹是敌 ...
- MySQL双主一致性架构优化
一.双主保证高可用 MySQL数据库集群常使用一主多从,主从同步,读写分离的方式来扩充数据库的读性能,保证读库的高可用,但此时写库仍然是单点. 在一个MySQL数据库集群中可以设置两个主库,并设置双向 ...
- DevExpress XtraGrid如何使单元格只读?
-----------------------------从别人那里copy来的-------------------------------------------------- 1. 设置Gr ...
- Oracle安装、Navicat for Oracle、JDBCl连接、获取表结构
Oracle安装 Navicat for Oracle配置 Oracle JDBC连接(增删改查) Oracle安装 环境windows 7 64位 安装版本:oracle 11g(64位) 下载地址 ...