这题太神仙了必须写博客。。。

显然可以想到二分答案。二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\)。

那么就可以写出代码了,树状数组套动态开点线段树即可。时间复杂度\(O(n(log_2n)^3)\)

然后因为出题人卡空间就炸了。。。如果256M就能过了。。

#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*f;
}
int n,m,fir[100010],nxt[200010],dis[200010],id;
il vd link(int a,int b){nxt[++id]=fir[a],fir[a]=id,dis[id]=b;nxt[++id]=fir[b],fir[b]=id,dis[id]=a;
}
int dfn[100010],dep[100010],fa[100010],siz[100010],son[100010];
il vd dfs(int x){siz[x]=1;for(int i=fir[x];i;i=nxt[i]){if(dep[dis[i]])continue;dep[dis[i]]=dep[x]+1;fa[dis[i]]=x;dfs(dis[i]);siz[x]+=siz[dis[i]];if(siz[son[x]]<=siz[dis[i]])son[x]=dis[i];}
}
int top[100010];
il vd dfs2(int x,int tp){top[x]=tp;dfn[x]=++dfn[0];if(son[x])dfs2(son[x],tp);for(int i=fir[x];i;i=nxt[i])if(fa[x]!=dis[i]&&son[x]!=dis[i])dfs2(dis[i],dis[i]);
}
int o[200010],u[200010],v[200010],w[200010];
int uni_w[200010],uni_w_tot;
int cnt,rt[200010],ls[15000001],rs[15000001],lz[15000001];
#define mid ((l+r)>>1)
il vd _update(int&x,int l,int r,const int&L,const int&R,const int&d){if(!x)x=++cnt;if(L<=l&&r<=R){lz[x]+=d;return;}if(L<=mid)_update(ls[x],l,mid,L,R,d);if(mid<R)_update(rs[x],mid+1,r,L,R,d);
}
il int _query(int&x,int l,int r,const int&p){if(!x)return 0;if(l==r)return lz[x];if(p<=mid)return lz[x]+_query(ls[x],l,mid,p);else return lz[x]+_query(rs[x],mid+1,r,p);
}
#undef mid
il vd Update(const int&p,const int&l,const int&r,const int&d){int x=p;while(x<=uni_w_tot)_update(rt[x],1,n,l,r,d),x+=x&-x;
}
il int Query(const int&p,const int&l){int x=p,ret=0;while(x)ret+=_query(rt[x],1,n,l),x-=x&-x;return ret;
}
int t[200010];
il vd bit_update(int x,int d){while(x<=uni_w_tot)t[x]+=d,x+=x&-x;}
il int bit_query(int x){int r=0;while(x)r+=t[x],x-=x&-x;return r;}
int main(){n=gi(),m=gi();for(int i=1;i<n;++i)link(gi(),gi());int RT=rand()%n+1;dep[RT]=1,dfs(RT),dfs2(RT,RT);for(int i=1;i<=m;++i){o[i]=gi();if(o[i]==0)u[i]=gi(),v[i]=gi(),w[i]=gi(),uni_w[++uni_w_tot]=-w[i];else if(o[i]==1){int t=gi();u[i]=u[t],v[i]=v[t],w[i]=w[t];}else if(o[i]==2)u[i]=gi();}std::sort(uni_w+1,uni_w+uni_w_tot+1);uni_w_tot=std::unique(uni_w+1,uni_w+uni_w_tot+1)-uni_w-1;for(int i=1;i<=m;++i)if(o[i]!=2)w[i]=std::lower_bound(uni_w+1,uni_w+uni_w_tot+1,-w[i])-uni_w;for(int i=1;i<=uni_w_tot;++i)uni_w[i]=-uni_w[i];for(int i=1;i<=m;++i){if(o[i]^2){int x=u[i],y=v[i],d=o[i]==0?1:-1;while(top[x]!=top[y])if(dep[top[x]]>dep[top[y]])Update(w[i],dfn[top[x]],dfn[x],d),x=fa[top[x]];else Update(w[i],dfn[top[y]],dfn[y],d),y=fa[top[y]];if(dfn[x]>dfn[y])std::swap(x,y);Update(w[i],dfn[x],dfn[y],d);bit_update(w[i],d);}else{if(!bit_query(uni_w_tot)){puts("-1");continue;}int l=1,r=uni_w_tot+1,mid;while(l<r){mid=((l+r)>>1);if(Query(mid,dfn[u[i]])==bit_query(mid))l=mid+1;else r=mid;}if(l<=uni_w_tot)printf("%d\n",uni_w[l]);else puts("-1");}}return 0;
}

然后学了一发神仙整体二分

大概就是说答案要用二分求,可以放在一起二分

大概就是void solve(int l,int r,int L,int R),就是\([L,R]\)的操作/询问,操作的权值都\(\in[l,r]\),这里面的查询都已经确定了在\([l,r]\)范围内。

如果\(l=r\)直接更新答案就好了,否则要确定这里面所有查询的

按时间顺序操作,如果当前是修改而且权值\(\geq mid\),就加入/删除一条u-v的路径;如果是询问就所有的路径是否都经过当前点即可,就能知道这个询问的答案是否\(\geq mid\)。具体实现可以简单树上差分。

然后递归调用下去。

然后代码为了卡常把\(\geq\)改成了\(\leq\),具体见代码。。

#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){int x=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x;
}
int n,m,fir[100010],nxt[200010],dis[200010],id;
il vd link(int a,int b){nxt[++id]=fir[a],fir[a]=id,dis[id]=b;nxt[++id]=fir[b],fir[b]=id,dis[id]=a;
}
int dfn[100010],dep[100010],fa[100010],siz[100010],son[100010];
il vd dfs(int x){siz[x]=1;for(int i=fir[x];i;i=nxt[i]){if(dep[dis[i]])continue;dep[dis[i]]=dep[x]+1;fa[dis[i]]=x;dfs(dis[i]);siz[x]+=siz[dis[i]];if(siz[son[x]]<=siz[dis[i]])son[x]=dis[i];}
}
int top[100010];
il vd dfs2(int x,int tp){top[x]=tp;dfn[x]=++dfn[0];if(son[x])dfs2(son[x],tp);for(int i=fir[x];i;i=nxt[i])if(fa[x]!=dis[i]&&son[x]!=dis[i])dfs2(dis[i],dis[i]);
}
struct ques{int o,u,v,w,i,lca;bool y;}s[200010],a[200010],b[200010];
int uni_w[200010],uni_w_tot,ans[200010];
int t[200010];
il vd update(int x,int d){while(x<=n)t[x]+=d,x+=x&-x;}
il int query(int x){int r=0;while(x)r+=t[x],x-=x&-x;return r;}
il vd solve(int l,int r,int L,int R){if(L>R)return;for(int i=L;i<=R;++i)if(s[i].o==2)goto GG;return;GG:;if(l==r){for(int i=L;i<=R;++i)if(s[i].i)ans[s[i].i]=l;return;}int mid=(l+r)>>1,tot=0,A=0,B=0;for(int i=L;i<=R;++i)if(s[i].o==2){if(query(dfn[s[i].u]+siz[s[i].u]-1)-query(dfn[s[i].u]-1)==tot)b[++B]=s[i];else a[++A]=s[i];}else if(s[i].w<=mid){int d=s[i].o?-1:1;tot+=d;update(dfn[s[i].u],d);update(dfn[s[i].v],d);update(dfn[s[i].lca],-d);if(s[i].lca!=1)update(dfn[fa[s[i].lca]],-d);a[++A]=s[i];}else b[++B]=s[i];memcpy(s+L,a+1,(sizeof(ques))*A);memcpy(s+L+A,b+1,(sizeof(ques))*B);for(int i=L;i<=R;++i)if(s[i].o!=2&&s[i].w<=mid&&s[i].y){int d=s[i].o?1:-1;update(dfn[s[i].u],d);update(dfn[s[i].v],d);update(dfn[s[i].lca],-d);if(s[i].lca!=1)update(dfn[fa[s[i].lca]],-d);}solve(l,mid,L,L+A-1),solve(mid+1,r,L+A,R);
}
int main(){n=gi(),m=gi();for(int i=1;i<n;++i)link(gi(),gi());dep[1]=1,dfs(1),dfs2(1,1);for(int i=1;i<=m;++i){s[i].o=gi();if(s[i].o==0){s[i].u=gi(),s[i].v=gi(),s[i].w=gi(),uni_w[++uni_w_tot]=-s[i].w;s[i].y=1;int x=s[i].u,y=s[i].v;while(top[x]!=top[y]){if(dep[top[x]]>dep[top[y]])x=fa[top[x]];else y=fa[top[y]];}s[i].lca=(dep[x]<dep[y])?x:y;}else if(s[i].o==1){int x=gi();s[i]=s[x],s[i].o=1;s[i].y=s[x].y=0;}else s[i].u=gi(),s[i].i=++ans[0];}uni_w[++uni_w_tot]=1;std::sort(uni_w+1,uni_w+uni_w_tot+1);uni_w_tot=std::unique(uni_w+1,uni_w+uni_w_tot+1)-uni_w-1;for(int i=1;i<=m;++i)if(s[i].o!=2)s[i].w=std::lower_bound(uni_w+1,uni_w+uni_w_tot+1,-s[i].w)-uni_w;for(int i=1;i<=uni_w_tot;++i)uni_w[i]=-uni_w[i];solve(1,uni_w_tot,1,m);for(int i=1;i<=ans[0];++i)printf("%d\n",uni_w[ans[i]]);return 0;
}

卡了一波常数就洛咕rk1,bzoj rk7了。。

upd:又改了一波 bzojrk1了

转载于:https://www.cnblogs.com/xzz_233/p/9884562.html

洛咕P3250 [HNOI2016]网络 整体二分相关推荐

  1. P3250 [HNOI2016]网络(整体二分)

    P3250 [HNOI2016]网络 给定一棵树,有三种操作: 给定u,v,wu, v, wu,v,w,表示u,vu, vu,v路径上有一个重要度为www的请求, 给定ttt,第ttt个发生的请求结束 ...

  2. P3250 [HNOI2016]网络(利用堆建线段树 + 树剖)

    P3250 [HNOI2016]网络 做法有点神奇!!!利用堆作为节点建立一颗线段树,用堆维护线段树上点的信息. 说说查询操作,我们的目的是要查询,没有经过这个点的事件最大值,考虑如何维护. 我们定义 ...

  3. 【洛谷1527】 [国家集训队]矩阵乘法(整体二分)

    传送门 洛谷 Solution 考虑看到什么k小就整体二分套上去试一下. 矩形k小整体二分+二维树状数组就好了. 代码实现 // luogu-judger-enable-o2 /*mail: mlea ...

  4. 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...

  5. 洛谷P1527 [国家集训队] 矩阵乘法 [整体二分,二维树状数组]

    题目传送门 矩阵乘法 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入格式: 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N* ...

  6. [HNOI2016]网络 树链剖分,堆

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

  7. 4538: [Hnoi2016]网络

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

  8. 【BZOJ1146】【CTSC2008】网络管理 [整体二分]

    网络管理 Time Limit: 50 Sec  Memory Limit: 162 MB [Submit][Status][Discuss] Description M公司是一个非常庞大的跨国公司, ...

  9. P3527 [POI2011]MET-Meteors 整体二分 + 树状数组

    洛谷 题意: 思路: 考虑整体二分前,一定要思考一下直接二分怎么做.显然对每个城市,当<pos<pos<pos的时候收集不够足够的陨石,>=pos>=pos>=po ...

最新文章

  1. sql优化常用的几种方法_MySQL常用30种SQL查询语句优化方法
  2. 计算机不会输入函数怎么办,函数不正确_电脑上文件打不开,显示函数不正确怎么解决?...
  3. django1.11.6+nginx1.12.2+uwsgi2.0.15 部署
  4. python简介及环境安装
  5. Linus 在圣诞节想提前放假做了这些解释,哈哈哈
  6. RAX,eax,ax,ah,al 关系
  7. hdu 4619 Warm up 2(并查集)
  8. Hash 函数的现状,2012
  9. uni-app使用阿里矢量图库导入 icon 彩色和黑白色
  10. C++游戏服务器框架笔记(二)_封装Socket类
  11. 金蝶系统提示服务器不是有效的,金蝶服务器不是有效的,请重新设置问题
  12. 通过IIS安装包安装IIS
  13. MMDetection(三):公开数据集上测试和训练模型
  14. 布尔-施罗德逻辑代数中的公设对应-- 布尔逻辑之六
  15. Vue打包后图片路径问题
  16. 国内十大资质正规黄金交易平台排名(2023名单汇总)
  17. VMProtect进行加壳
  18. 任正非:华为为什么要坚持工业科学管理
  19. IOS7系统最新漏洞
  20. python中用来结束整个循环的是_python break什么意思

热门文章

  1. CodeForces - 1000D:Yet Another Problem On a Subsequence (DP+组合数)
  2. 【软件工程】七、软件系统设计
  3. 【一起学UniGUI】--UniGUI的部署选项(5)
  4. 书法拓片matlab,[转载]碑帖拓片摹拓技法
  5. 【源码分析】Spring的循环依赖(setter注入、构造器注入、多例、AOP)
  6. android 系统相册删除照片,怎样恢复手机相册删除的照片?这几个方法你会用吗?...
  7. Spring - RabbitMQ循环依赖问题解决
  8. 关于图像变换的总结(仿射变换,刚体变换等)
  9. 软件开发公司管理手册
  10. 【笔记】信号与线性系统