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) ...
随机推荐
- linux 笔试题
一.填空题: 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统中每个文件用 i节点 来 ...
- mysql主从复制原理
复制如何工作 整体上来说,复制有3个步骤: (1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events): ...
- Git Tips
撤销已经推送到远程仓库的最后一次提交,要小心这么操作,因为远程仓库还有别人在使用 $ git reset --hard HEAD^ $ git push -f origin master 从仓库中提出 ...
- AX 与Citrix打印机问题
国外文章,抄个链接,备查 http://blogs.msdn.com/b/axsupport/archive/2010/07/06/ax-2009-citrix-amp-terminal-server ...
- python 安装加环境变量
pip install sth --global-option="build_ext" --global-option="-I/usr/local/include&quo ...
- java之源码路径及api
jav源码地址:D:\Program Files\jdk1.7\src.zip class类地址:D:\Program Files\jdk1.7\jre\lib\rt.jar 在线api底地址:htt ...
- CentOS7之VMware安装
选择CentOS的原因 起初也了解了几个linux的发行版,最终决定选择centOS的原因却很简单:阿里云和腾讯云提供的云服务器中centos的版本最多. VMware12的安装 下载地址:http ...
- [转]使用Xcode 4发布App 实例操作
使用xcode 4发布app 实例操作是本文介绍的内容,不多说,我们直接进入话题. 1.iOS Provisioning Portal 和iTunes Connect 没有变,下载与安装.mobile ...
- 转载:Linux kernel rt_mutex的背景和简介
From: http://blog.chinaunix.net/uid-23146151-id-3074045.html 最近在看linux rtmutex部分的实现过程,就像他注释中写的一样,还是比 ...
- SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework
3.1运行效果: 3.2开发实现: 3.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...