传送门
好久没更新题解了,感觉这道题思路不难,但做法挺多的,我大概能想到四种做法,如果有神犇还有其他好方法请在下方评论
1.树链剖分,每条重链维护一颗平衡树
修改直接做logn\log n
查询时二分答案,查找路径上重链中的平衡树,复杂度log3n\log^3 n
总复杂度O(nlogn+qlog3nO(n \log n+q\log^3 n)
常数大 不好写(因为set不能查询排名)但是是在线做法
2.带修主席树,维护每个叶子到根节点路径上的权值
修改直接做log2n\log^2 n
查询时把log\log个主席树放在一起查做到log2n\log^2 n
(感谢lucida的提醒)
总复杂度O(nlog2n+qlog2n)O(n \log^2 n+q \log^2 n)
常数中等,代码复杂度中等,可以做到在线
3.带修树上莫队,用树状数组维护插入和删除,查询时二分答案
总复杂度O(q(n23logn+log2n))O(q(n^{\frac 2 3} \log n+\log^2 n))
基本过不了,离线做法
4.整体二分,然后用树链剖分+树状数组维护权值
总复杂度O(nlogn+qlog3n)O(n \log n+q \log^3 n)
常数较小,代码复杂度中等,离线做法
(可能有复杂度分析不正确的地方,望指正)
整体二分中的单点修改操作,我用的方法是先减去之前的权值,再加上新的权值,所以修改操作相当于是原先的两倍
“第k大值”可以在求过lca后变为”求第k小值“
代码可读性不是很高。。。见谅
好像整体二分是可以做到log2n\log^2 n的?算了不管了。。。
代码:

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int n,m;
int a[80005],b[110005],ans[30005],dfn[80005],fa[80005],dep[80005],son[80005],siz[80005],top[80005],d[80005];
vector<int>e[80005];
struct opt{int k,x,y,id;
}q[140005],l[140005],r[140005];
int in()
{int t=0;char ch=getchar();for (;ch<'0'||ch>'9';ch=getchar());for (;ch>='0'&&ch<='9';ch=getchar()) t=t*10+(ch^48);return t;
}
void dfs1(int x)
{siz[x]=1;for (int v,i=0;i<e[x].size();++i){v=e[x][i];if (v==fa[x]) continue;fa[v]=x;dep[v]=dep[x]+1;dfs1(v);siz[x]+=siz[v];son[x]=(siz[son[x]]>siz[v]?son[x]:v);}
}
void dfs2(int x,int tp)
{top[x]=tp;dfn[x]=++dfn[0];if (son[x]) dfs2(son[x],tp);for (int i=0;i<e[x].size();++i)if (e[x][i]!=fa[x]&&e[x][i]!=son[x]) dfs2(e[x][i],e[x][i]);
}
void add(int x,int val)
{for (;x<=n;x+=x&-x) d[x]+=val;
}
int get(int x)
{int t=0;for (;x;x-=x&-x) t+=d[x];return t;
}
int cal(int x,int y)
{int t=0;for (;top[x]!=top[y];x=fa[top[x]]){if (dep[top[x]]<dep[top[y]]) swap(x,y);t+=get(dfn[x])-get(dfn[top[x]]-1);}if (dep[x]<dep[y]) swap(x,y);return t+get(dfn[x])-get(dfn[y]-1);
}
int lca(int x,int y)
{for (;top[x]!=top[y];x=fa[top[x]])if (dep[top[x]]<dep[top[y]]) swap(x,y);return dep[x]<dep[y]?x:y;
}
void solve(int L,int R,int Lo,int Ro)
{if (L==R){for (int i=Lo;i<=Ro;++i)if (q[i].k)if (q[i].k>0) ans[q[i].id]=b[R];else ans[q[i].id]=-1;return;}int mid=L+R>>1,lc=0,rc=0;for (int t,i=Lo;i<=Ro;++i)if (q[i].k){t=cal(q[i].x,q[i].y);if (t>=q[i].k) l[++lc]=q[i];else q[i].k-=t,r[++rc]=q[i];}else{if (q[i].y<=mid)l[++lc]=q[i],add(dfn[q[i].x],q[i].id);elser[++rc]=q[i];}for (int i=Lo;i<=Ro;++i)if (!q[i].k&&q[i].y<=mid) add(dfn[q[i].x],-q[i].id);for (int i=Lo;i<=Lo+lc-1;++i) q[i]=l[i-Lo+1];for (int i=Lo+lc;i<=Ro;++i) q[i]=r[i-Lo-lc+1];solve(L,mid,Lo,Lo+lc-1);solve(mid+1,R,Lo+lc,Ro);
}
main()
{n=in();m=in();for (int i=1;i<=n;++i)q[i]=(opt){0,i,a[i]=in(),1},b[++b[0]]=q[i].y;for (int u,v,i=1;i<n;++i)u=in(),v=in(),e[u].push_back(v),e[v].push_back(u);dfs1(1);dfs2(1,1);int cnt=0,qq=n;for (int i=1;i<=m;++i){q[++qq]=(opt){in(),in(),in(),0};if (q[qq].k){q[qq].id=++cnt;q[qq].k=dep[q[qq].x]+dep[q[qq].y]-2*dep[lca(q[qq].x,q[qq].y)]+2-q[qq].k;if (q[qq].k<=0) q[qq].k=-1;}else{b[++b[0]]=q[qq].y;q[qq].id=1;q[++qq]=q[qq-1];q[qq].id=-1;q[qq].y=a[q[qq].x];a[q[qq].x]=q[qq-1].y;swap(q[qq],q[qq-1]);}}sort(b+1,b+b[0]+1);b[0]=unique(b+1,b+b[0]+1)-b-1;for (int i=1;i<=qq;++i)if (!q[i].k) q[i].y=lower_bound(b+1,b+b[0]+1,q[i].y)-b;solve(1,b[0],1,qq);for (int i=1;i<=cnt;++i)if (ans[i]==-1) puts("invalid request!");else printf("%d\n",ans[i]);
}

【BZOJ1146】网络管理,整体二分相关推荐

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

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

  2. P4175 [CTSC2008]网络管理(整体二分)

    P4175 [CTSC2008]网络管理 给定一棵有nnn个节点的树,点有点权,有两种操作:① 修改某个点的点权,② 查询两点路径间的点权第kkk大. 给定u,vu, vu,v,选定111号节点为根节 ...

  3. bzoj1146整体二分+树链剖分+树状数组

    其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 1 #include<cstdio> 2 #include< ...

  4. SP3946 MKTHNUM - K-th Number(整体二分)

    思路 整体二分的板子题,没什么思路好说 代码 #include <cstdio> #include <algorithm> #include <cstring> u ...

  5. BZOJ2738 矩阵乘法 【整体二分 + BIT】

    题目链接 BZOJ2738 题解 将矩阵中的位置取出来按权值排序 直接整体二分 + 二维BIT即可 #include<algorithm> #include<iostream> ...

  6. [bzoj2527][Poi2011]Meteors_整体二分_树状数组

    Meteors bzoj-2527 Poi-2011 题目大意:题目链接. 注释:略. 想法: 首先答案可以离线,且具有单调性. 这里的单调性就是随着时间的推移,每个国家收集的陨石数增加. 不难想到整 ...

  7. 【BZOJ2738】矩阵乘法 [整体二分][树状数组]

    矩阵乘法 Time Limit: 20 Sec  Memory Limit: 256 MB [Submit][Status][Discuss] Description 给你一个N*N的矩阵,不用算矩阵 ...

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

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

  9. 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组

    题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...

最新文章

  1. [洛谷1383]高级打字机 题解
  2. Nginx和uWSGI和Flask的关系
  3. opencart mail.php,如何修改OpenCart系统发信邮箱模板
  4. 【网站】 简单通用微信QQ跳转浏览器打开代码
  5. RabbitMQ架构模型(一)
  6. 阿里云构建Jenkins服务
  7. 20155338《网络对抗》Web安全基础实践
  8. 【大一期末项目】qqclienkey利用:基于qqclientkey的纯c++项目实践
  9. Netty权威指南电子版(不要积分点个赞就好)
  10. 【院校信息】2021北京航空航天大学计算机考研数据汇总
  11. “你的论文充斥着垃圾,写作一塌糊涂,我读着读着都想撕了它”
  12. Android 框架MVP
  13. JS中substr和substring
  14. DIV自动填满剩余空间
  15. mongoDB百度脑图总结
  16. 别笑话爬虫工程师了,数仓库工程师也被警察传话了。
  17. 熊猫烧香制造者李俊出狱后开软件公司
  18. HTML网页悬浮按钮
  19. FreeRapid v0.9u3
  20. python使用turtle绘制叠加等边三角形

热门文章

  1. 【DevCloud · 敏捷智库】Scrum和看板如何选择
  2. 【Python3网络爬虫开发实战】1.3.3-pyquery的安装
  3. python解析response的json_python:解析requests返回的response(json格式)说明
  4. MATLAB绘图辅助操作
  5. python scrapy框架爬虫_Python Scrapy爬虫框架
  6. Matlab中矩阵编号方式以及一维二维三维数据间的相互转换
  7. m1芯片Mac安装Apple版TensorFlow(conda-forge)+编译安装sklearn
  8. sql group by 取每组符合条件_SPL 简化 SQL 案例详解:计算各组前 N 行
  9. Spark MLlib之K-Means聚类算法
  10. Excel的导入与导出