luogu P3250 [HNOI2016]网络

时间:2023-01-03 15:42:35

传送门

考虑只有一个询问,怎么使用暴力枚举最快的得到答案.因为要求最大的,所以可以把链按权值从大往小排序,然后往后扫,找到一个没有交的就是答案,直接退出

一堆询问,可以考虑整体二分,先二分一个值\(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]网络的更多相关文章

  1. P3250 &lbrack;HNOI2016&rsqb;网络

    LINK:网络 一棵树 每次添加一条路径 或者删除之前的一条路径 或询问除了不经过某个点之外剩下的最大值. 一个显然的思路 对于一条路径的权值我们直接把权值塞上去 标记永久化一下即可. 考虑如何求答案 ...

  2. 洛咕P3250 &lbrack;HNOI2016&rsqb;网络 整体二分

    这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...

  3. &lbrack;洛谷P3250&rsqb;&lbrack;HNOI2016&rsqb;网络

    题目大意:给定一棵树.有三种操作: $0\;u\;v\;t:$在$u$到$v$的链上进行重要度为$t$的数据传输. $1\;x:$结束第$x$个数据传输. $2\;x:$询问不经过点$x$的数据传输中 ...

  4. 洛谷P3250 &lbrack;HNOI2016&rsqb;网络(整体二分&plus;树状数组&plus;树剖)

    传送门 据说正解是树剖套堆???然而代码看着稍微有那么一点点长…… 考虑一下整体二分,设当前二分到的答案为$mid$,如果所有大于$mid$的边都经过当前点$x$,那么此时$x$的答案必定小于等于$m ...

  5. 并不对劲的bzoj4538&colon;loj2049&colon;p3250&colon;&lbrack;HNOI2016&rsqb;网络

    题意 有一棵\(n\)(\(n\leq 10^5\))个点的树,\(m\)(\(m\leq 2\times 10^5\))个操作.操作有三种:1.给出\(u,v,k\),表示加入一条从\(u\)到\( ...

  6. BZOJ 4538&colon; &lbrack;Hnoi2016&rsqb;网络 &lbrack;整体二分&rsqb;

    4538: [Hnoi2016]网络 题意:一棵树,支持添加一条u到v权值为k的路径,删除之前的一条路径,询问不经过点x的路径的最大权值 考虑二分 整体二分最大权值,如果\(k \in [mid+1, ...

  7. 【LG3250】&lbrack;HNOI2016&rsqb;网络

    [LG3250][HNOI2016]网络 题面 洛谷 题解 30pts 对于\(m\leq 2000\),直接判断一下这个个点是否断掉一个交互,没断掉的里面取\(max\)即可,复杂度\(O(m^2\ ...

  8. 4538&colon; &lbrack;Hnoi2016&rsqb;网络

    4538: [Hnoi2016]网络 链接 分析: 整体二分. 对于一次操作,可以二分一个答案mid,判断权值大于mid的路径是否全部经过这个点.如果是 ,那么这次询问的答案在[l,mid-1]之间, ...

  9. &lbrack;HNOI2016&rsqb;网络 树链剖分,堆

    [HNOI2016]网络 LG传送门 表示乱搞比正解难想. 整体二分很好想吧. 但是为了好写快乐,我们选择三个\(\log\)的乱搞. 先树剖,线段树套堆维护区间最大值.对于一次修改,如果是插入,就把 ...

随机推荐

  1. Nvelocity用法

    NVelocity用法 NVelocity是一个基于.NET的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定 ...

  2. linux下MySQL表名忽略大小写设置

    最近公司项目的MySQL数据库要迁移到linux下,部署时日志总是显示报找不到一个表,用MYSQL查看明明有这个表.后来经百度,原来LINUX下的MYSQL默认是区分表名大小写的. 用命令查看当前是否 ...

  3. 【转】MySQL5安装的图解(mysql-5&period;0&period;27-win32&period;zip)

    转载地址:http://blog.csdn.net/xssh913913/article/details/1713182 MySQL5安装的图解(最新版) http://hi.baidu.com/yu ...

  4. 构建maven项目3

    1.1.创建Jave Project 1.使用mvn archetype:generate命令,如下所示: mvn archetype:generate -DgroupId=com.mycompany ...

  5. phonegap WebApp

    打开网页浏览器,进入Android SDK网站(http://developer.android.com/sdk/index.html). 我们可以看到,Google官方提供了包括Windows平台在 ...

  6. uitextField单词的方法和抖动的限制

    这种方法还可以找到在线. 如下面的详细信息: .h文件 #import <UIKit/UIKit.h> @interface UITextField (LimitLength) /** * ...

  7. Arrays&period;sort解析

    Arrays.sort()解读 在学习了排序算法之后, 再来看看 Java 源码中的, Arrays.sort() 方法对于排序的实现. 都是对基本数据类型的排序实现, 下面来看看这段代码: Arra ...

  8. java Servlet生成随机验证码

    import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; i ...

  9. &period;NET项目引用黄色小三角以及找不到依赖的解决方法

    上图,问题描述: 经过查证,这个是引用的项目框架版本和本项目框架版本不一致的症状. 解决办法: 点击项目右键属性,调整版本使两个项目的版本一致 问题解决.good! ----------------- ...

  10. Python代码转换为exe可执行程序详解

    1:安装pyinstaller pip install pyinstaller 2,制作exe 1,先写一个hello.py print('hello world!') input() 2.执行(在s ...