bzoj1146整体二分+树链剖分+树状数组
其实也没啥好说的
用树状数组可以O(logn)的查询
套一层整体二分就可以做到O(nlngn)
最后用树链剖分让序列上树
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline int read()
{
int x=,f=,ch=getchar();
while(ch<''||ch>''){if(ch=='-'){f=-;}ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,q;
int data[];
inline void add(int x,int i)
{
while(x<=n)
{
data[x]+=i;
x+=x&(-x);
}
}
inline int query(int x)
{
int res=;
while(x>=)
{
res+=data[x];
x-=x&(-x);
}
return res;
}
int h[],next[],to[],cnt;
inline void addedge(int x,int y)
{
next[cnt]=h[x];
to[cnt]=y;
h[x]=cnt;
cnt++;
}
int size[],hson[],dep[],f[];
inline void bfs(int x,int fa)
{
int i;
size[x]=;
for(i=h[x];i!=-;i=next[i])
{
if(to[i]==fa)
{
continue;
}
dep[to[i]]=dep[x]+;
f[to[i]]=x;
bfs(to[i],x);
size[x]+=size[to[i]];
if(size[to[i]]>size[hson[x]])
{
hson[x]=to[i];
}
}
}
int up[],first[],tim;
inline void spfa(int x,int tt)
{
tim++;
first[x]=tim;
up[x]=tt;
if(!hson[x])
{
return ;
}
spfa(hson[x],tt);
int i;
for(i=h[x];i!=-;i=next[i])
{
if(to[i]==f[x]||to[i]==hson[x])
{
continue;
}
spfa(to[i],to[i]);
}
}
inline int lca(int x,int y)
{
int res=;
while(up[x]!=up[y])
{
if(dep[up[x]]<dep[up[y]])
{
swap(x,y);
}
res+=query(first[x])-query(first[up[x]]-);
x=f[up[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
res+=query(first[y])-query(first[x]-);
return res;
}
struct stu
{
int op,l,r,id,x;
};
stu a[];
int ans[];
int m[];
stu q1[],q2[];
inline void erfen(int l,int r,int sl,int sr)
{
if(sl>sr)
{
return ;
}
if(l==r)
{
int i;
for(i=sl;i<=sr;i++)
{
if(a[i].op!=)
{
continue;
}
ans[a[i].id]=l;
}
return ;
}
int i,mid=(l+r)>>,k,cnt1=,cnt2=;
for(i=sl;i<=sr;i++)
{
if(a[i].op==)
{
if(a[i].x<=mid)
{
add(first[a[i].l],);
m[i]=;
}
else
{
m[i]=;
}
continue;
}
if(a[i].op==)
{
if(a[i].x<=mid)
{
add(first[a[i].l],-);
m[i]=;
}
else
{
m[i]=;
}
continue;
}
if(a[i].op==)
{
k=lca(a[i].l,a[i].r);
if(k<a[i].x)
{
a[i].x-=k;
m[i]=;
}
else
{
m[i]=;
}
}
}
for(i=sl;i<=sr;i++)
{
if(a[i].op==)
{
if(a[i].x<=mid)
{
add(first[a[i].l],-);
}
}
if(a[i].op==)
{
if(a[i].x<=mid)
{
add(first[a[i].l],);
}
}
if(m[i]==)
{
cnt1++;
q1[cnt1]=a[i];
}
else
{
cnt2++;
q2[cnt2]=a[i];
}
}
for(i=;i<=cnt1;i++)
{
a[sl+i-]=q1[i];
}
for(i=;i<=cnt2;i++)
{
a[sl+cnt1+i-]=q2[i];
}
erfen(l,mid,sl,sl+cnt1-);
erfen(mid+,r,sl+cnt1,sr);
}
int p[];
int main()
{
memset(h,-,sizeof(h));
memset(ans,0x3f,sizeof(ans));
n=read(),q=read();
int i,x,y,tail=,k,o;
for(i=;i<=n;i++)
{
x=read();
tail++;
a[tail].op=,a[tail].l=i,a[tail].x=x;
p[i]=x;
}
for(i=;i<n;i++)
{
x=read(),y=read();
addedge(x,y);
addedge(y,x);
}
dep[]=;
bfs(,-);
spfa(,);
for(i=;i<=n;i++)
{
add(first[i],);
}
for(i=;i<=q;i++)
{
k=read(),x=read(),y=read();
if(k==)
{
tail++;
a[tail].op=;a[tail].l=x,a[tail].x=p[x];
tail++;
a[tail].op=;a[tail].l=x;a[tail].x=y;
p[x]=y;
}
else
{
o=lca(x,y);
if(o<k)
{
ans[i]=-;
continue;
}
k=o-k+;
tail++;
a[tail].op=,a[tail].l=x,a[tail].r=y,a[tail].x=k;
a[tail].id=i;
}
}
memset(data,,sizeof(data));
erfen(,,,tail);
for(i=;i<=q;i++)
{
if(ans[i]==0x3f3f3f3f)
{
continue;
}
if(ans[i]==-)
{
puts("invalid request!");
}
else
{
printf("%d\n",ans[i]);
}
}
return ;
}
bzoj1146整体二分+树链剖分+树状数组的更多相关文章
- hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...
- HDU 5044 (树链剖分+树状数组+点/边改查)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变 ...
- hdu 3966 Aragorn's Story(树链剖分+树状数组)
pid=3966" target="_blank" style="">题目链接:hdu 3966 Aragorn's Story 题目大意:给定 ...
- (简单) POJ 3321 Apple Tree,树链剖分+树状数组。
Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...
- Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...
- HDU 3966 Aragorn's Story (树链剖分+树状数组)
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- 学习之路三十八:Hook(钩子)的学习
好久没写文章了,还记得年前面试了一家公司,为了检测一下我的学习能力,给了我一个任务,做一个自动登录并自动操作菜单的程序. 花了几天的时间研究了Hook以及使用WindowsAPI操作程序的知识,现在记 ...
- 配置ST3在浏览器中打开
打开Preferences - 「Key Bindings - User」,添加此行: {"keys": ["f1"],"command": ...
- GitHub 操作流程示例
最新文章:Virson's Blog 参考文章: 博客园-Web前端开发,博客园-喻头快跑,GotGitHub 首先.通过github网站新建一个仓库,得到仓库地址 https://github.co ...
- 让IE8支持HTML5及canvas功能!
微软出的IE9支持HTML5,但因为不支持XP系统,暂时我还用不了. 即使能用,现阶段如果开发HTML5页面,并考虑到兼容性问题的话,恐怕也得让自己的界面支持IE6-8吧. 首先,需要让IE支持HTM ...
- 算法导论第十八章 B树
一.高级数据结构 本章以后到第21章(并查集)隶属于高级数据结构的内容.前面还留了两章:贪心算法和摊还分析,打算后面再来补充.之前的章节讨论的支持动态数据集上的操作,如查找.插入.删除等都是基于简单的 ...
- Unity Remote 4安卓机使用指南
必须U3D版本为4.5以上,可以在Public目录下载.想实时调试IOS版本必须是MAC系统! 优点:可以在不编译的情况下实时的去调试真实Android设备的各种情况,包括使用触摸功能(Remote接 ...
- Mysql 导入数据,推荐Source命令,太快了
http://jingyan.baidu.com/article/cbf0e500d15c762eab289362.html
- 解决php中echo出来的汉子乱码
问的人太多了,就列出来展示给大家! 需要了解的概念: Content-Type:用于定义用户的浏览器或相关设备如何显示将要加载的数据,或者如何处理将要加载的数据 MIME:MIME类型就是设定某种扩展 ...
- Chart 点击获取坐标
private void chart2_MouseMove(object sender, MouseEventArgs e) { if (!this.DesignMode) { ].AxisX.Sca ...
- struts2整合CKEditor和CKFinder实现上传
上一篇文章给大家分享了CKEditor+CKFinder+JSP实现了在线编辑器上传图片的功能,这里在给大家分享一下如何在前面的基础上在struts2下实现这样的功能. 实现与Struts2的整合,整 ...