令人抓狂的整体二分题。根本原因还是我太菜了。

在学校写了一个下午写得头晕,回家里重写了一遍,一个小时就写完了……不过还是太慢。

题目传送门:洛谷P4175。

题意简述:

一棵 \(n\) 个结点的树,每个点有点权。

有 \(m\) 次操作,每个操作要么是更改单点点权,要么是查询树链上第 \(k\) 大点权。

题解:

树套树固然可以,但是整体二分也很好。

整体二分就是对于所有的询问一起二分答案,在二分区间范围内的查询和修改一并下传。

这题把整体二分基础题的操作搬到了链上,但是实现方法并没有太大不同。

初始点权看成增加点权,插入在所有操作的最前面即可。
更改点权可以看成删除点权再增加点权,变成两次修改即可。

这题整体二分要求第 \(k\) 大,考虑二分出的答案 \(mid\),将大于 \(mid\) 的修改转成单点权值 \(\pm 1\),
而对于树链查询第 \(k\) 大,则转化成链上权值之和是否等于 \(k\)。

写整体二分题永远要注意二分的条件,我的条件是,链上大于 \(mid\) 的点数小于 \(k\) 个则答案小于等于 \(mid\),否则答案大于 \(mid\)。

单点修改,树链查询要是还用树剖就太naive了,套路转化:

考虑每个节点维护到根的路径上的信息,那么单点修改就变成子树修改,链查就变成四个单点查了(需要求LCA)。

而子树是一个区间,区间加法,单点查询;再使用树状数组差分技巧转化成单点差分,区间前缀和。

注意到还要求LCA,直接在DFS的时候用Tarjan处理就好了。

关于判断无解:当然可以直接处理掉……不过这样就必须求树链长度了。
我的方法是,往权值里面加一个-1,如果答案是-1,则真实答案应该是无解。

我的代码还离散化了权值,其实没用……

其他恶心的地方就是整体二分基本功了,太弱了调了好久……注意循环变量是指向真实操作的下标的指针还是真实操作的下标,如果你写结构体当我没说。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MN=80005;
const int MM=110005;
const int MQ=140005;
int n,m,q,w[MN],d[MQ],c;
int o[MQ],a[MQ],b[MQ],p[MQ],lc[MQ],ans[MQ];
int eh[MN],qh[MN],nxt[MM*2],to[MM*2],tot;
inline void ins(int*h,int x,int y){nxt[++tot]=h[x],to[tot]=y,h[x]=tot;}
int ld[MN],rd[MN],faz[MN],dfc;
int fa[MN];int ff(int x){return fa[x]?fa[x]=ff(fa[x]):x;}
void dfs(int u,int f){faz[u]=f,ld[u]=++dfc;for(int i=eh[u];i;i=nxt[i])if(to[i]!=f)dfs(to[i],u),fa[to[i]]=u;for(int i=qh[u];i;i=nxt[i])if(lc[to[i]])lc[to[i]]=ff(lc[to[i]]);else lc[to[i]]=u;rd[u]=dfc;
}
int B[MN];
inline void I(int i,int x){for(;i<=n;i+=i&-i)B[i]+=x;}
inline int Q(int i){int a=0;for(;i;i-=i&-i)a+=B[i];return a;}
int t[MQ];
void s(int l,int r,int L,int R){if(l>r)return;if(L==R){for(int i=l;i<=r;++i)ans[p[i]]=L;return;}int m=L+R>>1,p1=l-1,p2=r+1;for(int j=l,i;j<=r;++j){if(o[i=p[j]]>0){int x=Q(ld[a[i]])+Q(ld[b[i]])-Q(ld[lc[i]])-Q(ld[faz[lc[i]]]);if(x<o[i])o[i]-=x,t[++p1]=i;else t[--p2]=i;}else if(b[i]>m){I(ld[a[i]],o[i]?-1:1),I(rd[a[i]]+1,o[i]?1:-1);t[--p2]=i;}else t[++p1]=i;}for(int i=l;i<=r;++i)if(o[p[i]]<=0&&b[p[i]]>m)I(ld[a[p[i]]],o[p[i]]?1:-1),I(rd[a[p[i]]]+1,o[p[i]]?-1:1);reverse(t+p2,t+r+1),memcpy(p+l,t+l,r-l+1<<2);s(l,p1,L,m),s(p2,r,m+1,R);
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;++i)scanf("%d",&w[i]),o[++q]=0,a[q]=i,b[q]=w[i],p[q]=q;for(int i=1,x,y;i<n;++i)scanf("%d%d",&x,&y),ins(eh,x,y),ins(eh,y,x);for(int i=1;i<=m;++i){++q,scanf("%d%d%d",&o[q],&a[q],&b[q]),p[q]=q;if(!o[q])o[++q]=-1,a[q]=a[q-1],b[q]=w[a[q-1]],p[q]=q,w[a[q-1]]=b[q-1];}for(int i=1;i<=q;++i)if(o[i]>0)ins(qh,a[i],i),ins(qh,b[i],i);else d[++c]=b[i];d[++c]=-1;sort(d+1,d+c+1);c=unique(d+1,d+c+1)-d-1;for(int i=1;i<=q;++i)if(o[i]<=0)b[i]=lower_bound(d+1,d+c+1,b[i])-d;dfs(1,0),s(1,q,1,c);for(int i=1;i<=q;++i)if(o[i]>0)ans[i]==1?puts("invalid request!"):printf("%d\n",d[ans[i]]);return 0;
}
// 20:08 - 21:03

转载于:https://www.cnblogs.com/PinkRabbit/p/10182061.html

洛谷 P4175: bzoj 1146: [CTSC2008]网络管理相关推荐

  1. BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )

    树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...

  2. bzoj 1146 [CTSC2008]网络管理Network

    很久之前写过 count on the tree. 然后一直不懂树状数组是怎么套上这个主席树的. 看了两小时发现它套的就是个权值线段树, 看不出来可持久化在哪里. 因为动态开点所以空间nlog2n. ...

  3. 洛谷 P4151 BZOJ 2115 [WC2011]最大XOR和路径

    //bzoj上的题面太丑了,导致VJ的题面也很丑,于是这题用洛谷的题面 题面描述 XOR(异或)是一种二元逻辑运算,其运算结果当且仅当两个输入的布尔值不相等时才为真,否则为假. XOR 运算的真值表如 ...

  4. 洛谷 P2046 BZOJ 2007 海拔(NOI2010)

    题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...

  5. 洛谷 3784(bzoj 4913) [SDOI2017]遗忘的集合——多项式求ln+MTT

    题目:https://www.luogu.org/problemnew/show/P3784 https://www.lydsy.com/JudgeOnline/problem.php?id=4913 ...

  6. 洛谷 P4546 bzoj 5020 在美妙的数学王国中畅游 —— LCT+泰勒展开

    题目:https://www.luogu.org/problemnew/show/P4546 先写了个55分的部分分,直接用LCT维护即可,在洛谷上拿了60分: 注意各处 pushup,而且 spla ...

  7. 洛谷 P4300 BZOJ 1266 [AHOI2006]上学路线route

    题目描述 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:"很 ...

  8. 洛谷 P2590 BZOJ 1036 [ZJOI2008]树的统计

    Time limit 10000 ms//另外,BZOJ只算所有点的总时限,所以可能会放过一些原本会TLE的代码 Memory limit 165888 kB OS Linux SourceZJOI2 ...

  9. 洛谷 2312 / bzoj 3751 解方程——取模

    题目:https://www.luogu.org/problemnew/show/P2312 https://www.lydsy.com/JudgeOnline/problem.php?id=3751 ...

最新文章

  1. Win平台使用cmake工具生成sln工程示例
  2. SCSE 21fall 课程
  3. c语言mfc弹出窗口函数,CMFCDesktopAlertWnd实现桌面弹出消息框
  4. spring react_使用Spring WebFlux构建React性REST API –第2部分
  5. html搜索框 模糊搜索,前端js模糊搜索(模糊查询)
  6. SQL:postgresql查询结果加一个自定义的列
  7. Java做一个弹出表,至少有两个字段的简单的弹出窗体java表单
  8. MySQL 导入数据 时间数据 不准确 解决办法
  9. 登录网易云显示服务器地址,[网易云音乐]登录流程还原
  10. 微信小程序 全面屏适配
  11. 安卓手机各种信息获取---(通讯录短信息通话记录)
  12. git如何忽略文件或者文件夹
  13. libreoffice 出现 /lib/x86_64-linux-gnu/libcairo.so.2: undefined symbol: FT_Get_Var_Design_Coordi
  14. 手机视频监控软件功能需求
  15. 盒子垂直居中的三种办法
  16. Matlab:实现Fra单缝衍射仿真
  17. 【JY】ETABS塑性铰参数详解
  18. 很高兴顺利通过PMP考试!
  19. pb6连接本地sqlserver连不上连远程服务器可以连上,sql server 2008和PB9连接不上 怎么处理呀...
  20. VoLTE学习笔记(1)

热门文章

  1. 2. JSF---托管Bean
  2. 使用nginx在Windows部署网站https服务
  3. Java 输入两个数并输出它们的和
  4. STC89C52单片机 LCD1602液晶显示屏
  5. 华中科技大学 教学大纲 计算机,教学大纲-华中科技大学计算机学院
  6. mysql 创建师徒_mysql基础整理
  7. adobe Photoshop CS6 MAC中文版
  8. 【洛谷5251】[LnOI2019] 第二代图灵机(线段树+ODT)
  9. Spring中使用RedisTemplate操作Redis(spring-data-redis)
  10. fhqtreap的学习笔记