luogu P3250 [HNOI2016]网络
考虑只有一个询问,怎么使用暴力枚举最快的得到答案.因为要求最大的,所以可以把链按权值从大往小排序,然后往后扫,找到一个没有交的就是答案,直接退出
一堆询问,可以考虑整体二分,先二分一个值\(mid\),然后从前往后扫,如果是加入/删除操作,并且权值\(> mid\)就把这个操作贡献记上;如果是询问,然后如果经过这个点的链个数\(\ne\)当前存在的链个数,说明答案\(>mid\),否则\(\le mid\)
然后剩下的套一个整体二分板子就好了.答案的话如果取值范围的\(l=r\),就可以直接更新答案.然后就是怎么算经过某个点的链条数,显然可以使用洛谷树链剖分模板题的代码(别用无脑线段树,这里只要单点求值),或者考虑树上差分,每次询问子树内权值和就是那个链条数
#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register
using namespace std;
const int N=2e5+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N],nt[N],hd[N],tot=1;
il void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
}
int fa[N],sz[N],de[N],hs[N],top[N],dfn[N],ti;
void dfs1(int x)
{
sz[x]=1;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
fa[y]=x,de[y]=de[x]+1,dfs1(y),sz[x]+=sz[y];
hs[x]=sz[hs[x]]>sz[y]?hs[x]:y;
}
}
void dfs2(int x,int ntp)
{
dfn[x]=++ti,top[x]=ntp;
if(hs[x]) dfs2(hs[x],ntp);
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]||y==hs[x]) continue;
dfs2(y,y);
}
}
int n,q;
int c[N];
void ad(int x,int y){while(x<=n) c[x]+=y,x+=x&(-x);}
int gsm(int x){int an=0;while(x) an+=c[x],x-=x&(-x);return an;}
void add(int x,int y,int z)
{
while(top[x]!=top[y])
{
if(de[top[x]]<de[top[y]]) swap(x,y);
ad(dfn[top[x]],z),ad(dfn[x]+1,-z);
x=fa[top[x]];
}
if(de[x]>de[y]) swap(x,y);
ad(dfn[x],z),ad(dfn[y]+1,-z);
}
struct node
{
int x,y,z,k;
}p[N],lp[N],rp[N];
int an[N],m;
void dc(int l,int r,int lx,int rx)
{
if(l>r||lx>rx) return;
int sd=0;
if(lx==rx)
{
for(int i=l;i<=r;++i)
{
if(p[i].k) sd+=p[i].k,add(p[i].x,p[i].y,p[i].k);
else if(gsm(dfn[p[i].x])!=sd) an[p[i].y]=lx;
}
for(int i=l;i<=r;++i)
if(p[i].k) sd+=p[i].k,add(p[i].x,p[i].y,-p[i].k);
return;
}
int mid=(lx+rx)>>1;
int tl=0,tr=0;
for(int i=l;i<=r;++i)
{
if(p[i].k)
{
if(p[i].z<=mid) lp[++tl]=p[i];
else
{
sd+=p[i].k;
rp[++tr]=p[i],add(p[i].x,p[i].y,p[i].k);
}
}
else
{
if(gsm(dfn[p[i].x])==sd) lp[++tl]=p[i];
else
{
rp[++tr]=p[i];
}
}
}
for(int i=1;i<=tl;++i) p[l+i-1]=lp[i];
for(int i=1;i<=tr;++i) p[l+tl+i-1]=rp[i];
for(int i=1;i<=tr;++i)
if(rp[i].k) add(rp[i].x,rp[i].y,-rp[i].k);
dc(l,l+tl-1,lx,mid),dc(l+tl,r,mid+1,rx);
}
int main()
{
n=rd(),q=rd();
for(int i=1;i<n;++i) add(rd(),rd());
dfs1(1),dfs2(1,1);
for(int i=1;i<=q;++i)
{
int op=rd();
if(op==0) p[i].x=rd(),p[i].y=rd(),p[i].z=rd(),p[i].k=1;
else if(op==1)
{
int x=rd();
p[i]=p[x],p[i].k=-1;
}
else p[i].x=rd(),an[p[i].y=++m]=-1;
}
dc(1,q,0,1<<30);
for(int i=1;i<=m;++i) printf("%d\n",an[i]);
return 0;
}
luogu P3250 [HNOI2016]网络的更多相关文章
- P3250 [HNOI2016]网络
LINK:网络 一棵树 每次添加一条路径 或者删除之前的一条路径 或询问除了不经过某个点之外剩下的最大值. 一个显然的思路 对于一条路径的权值我们直接把权值塞上去 标记永久化一下即可. 考虑如何求答案 ...
- 洛咕P3250 [HNOI2016]网络 整体二分
这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...
- [洛谷P3250][HNOI2016]网络
题目大意:给定一棵树.有三种操作: $0\;u\;v\;t:$在$u$到$v$的链上进行重要度为$t$的数据传输. $1\;x:$结束第$x$个数据传输. $2\;x:$询问不经过点$x$的数据传输中 ...
- 洛谷P3250 [HNOI2016]网络(整体二分+树状数组+树剖)
传送门 据说正解是树剖套堆???然而代码看着稍微有那么一点点长…… 考虑一下整体二分,设当前二分到的答案为$mid$,如果所有大于$mid$的边都经过当前点$x$,那么此时$x$的答案必定小于等于$m ...
- 并不对劲的bzoj4538:loj2049:p3250:[HNOI2016]网络
题意 有一棵\(n\)(\(n\leq 10^5\))个点的树,\(m\)(\(m\leq 2\times 10^5\))个操作.操作有三种:1.给出\(u,v,k\),表示加入一条从\(u\)到\( ...
- P3250 [HNOI2016] 网络 (树剖+堆/整体二分+树上差分+树状数组)
解法1: 本题有插入路径和删除路径,在每个节点维护插入堆和删除堆,查询时两者top一样则一直弹出.如果每个节点维护的是经过他的路径,显然有些不好处理,正难则反,每个点维护不经过他的路径,那么x节点出了 ...
- BZOJ 4538: [Hnoi2016]网络 [整体二分]
4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...
- 【LG3250】[HNOI2016]网络
[LG3250][HNOI2016]网络 题面 洛谷 题解 30pts 对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\ ...
- 4538: [Hnoi2016]网络
4538: [Hnoi2016]网络 链接 分析: 整体二分. 对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点.如果是 ,那么这次询问的答案在[l,mid-1]之间, ...
随机推荐
- goroutine与调度器
29 November 2013 by skoo 我们都知道Go语言是原生支持语言级并发的,这个并发的最小逻辑单元就是goroutine.goroutine就是Go语言提供的一种用户态线程,当然这种用 ...
- C# Winfrom 进程&多线程
进程: 首先需要引用命名空间: using systemDiagnostics; 最简单的打开进程的方法,进程名并不是汉字: Process.start("calc");//cla ...
- 洛谷P1399 快餐店
题意:在基环树上找一点,使得这个点到所有点的距离最大值最小.这个点可以在某条边上. 解:很容易想到找出直径然后/2对吧...这里的直径是指任意两点间最短距离的最大值. 然而我这个SB冥思苦想了半天之后 ...
- 【洛谷P2585】三色二叉树
题目大意:给定一个二叉树,可以染红绿黄三种颜色,要求父节点和子节点的颜色不同,且如果一个节点有两个子节点,那么两个子节点之间的颜色也不同.求最多和最少有多少个节点会被染成绿色. 题解:加深了对二叉树的 ...
- (转)MySQL中In与Exists的区别
背景:总结mysql相关的知识点. 如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件. select * from user where exists s ...
- win32-api: 让 static 控件中的水平横行,垂直居中。
CreateWindowEx(....., SS_CENTER | SS_CENTERIMAGE); SS_CENTER 能让文字水平居中. SS_CENTERIMAGE 能让文字垂直居中. htt ...
- bat 复制文件夹,文件名递增 等操作
句尾无';' @echo off : 回显,使命令不在dos中一行一行输出 pause : 暂停,以便看到输出结果 变量 %% 与 % % : https://zhidao.baidu.com/que ...
- 做IT项目管理也需要具备产品思维
不知道大家有没有听过大胡子姜志辉老师的公开课,我自己认为讲的还是不错的. 因为本身大胡子老师就是一个IT行业的人士,自己还经历了程序员.架构师.项目经理.敏捷教练.产品经理.公司持有人等多个角色.所以 ...
- Linux设备树(二 节点)
二 节点(node)的表示 首先说节点的表示方法,除了根节点只用一个斜杠“/”表示外,其他节点的表示形式如“node-name@unit-address”.@前边是节点名字,后边是节点地址.节点名字的 ...
- go config
安装导入 go get github.com/astaxie/beego/config import "github.com/astaxie/beego/config" 使用 配置 ...