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) ...
随机推荐
- C#排序比较
与C#定义了相等性比较规范一样,C#也定义了排序比较规范,以确定一个对象与另一个对象的先后顺序.排序规范如下 IComparable接口(包括IComparable接口和IComparable< ...
- c#上iOS apns p12文件制作记录
1.在桌面上建一个"apns_p12"文件夹,所有的保存和生成文件都放在这里 2.从钥匙串中生成CertificateSigningRequest.certSigningReque ...
- js实现表单序列化的两种方法。
function serialize(form) { var parts = [], elems = form.elements, i = , len = elems.length, filed = ...
- 配置ST3在浏览器中打开
打开Preferences - 「Key Bindings - User」,添加此行: {"keys": ["f1"],"command": ...
- mac 自动配置java版本
首先输入命令:vi .bash_profile ,添加如下内容: # Mac默认 JDK (Mac默认自带了一个jdk6版本) export JAVA_6_HOME=`/usr/libexec/jav ...
- IL速查
名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. Add.Ovf.Un 将两个无符号整数值相加,执行溢出检查,并且 ...
- SNF开发平台WinForm之四-开发-主细表管理页面-SNF快速开发平台3.3-Spring.Net.Framework
4.1运行效果: 4.2开发实现: 4.2.1 有了第一个程序的开发,代码生成器的配置应该是没有问题了,我们只要在对应的数据库中创建我们需要的表结构就可以了,如下: 主表结构如下: ...
- css3 keyframes在yuicompressor下压缩问题
@keyframes proBackAction { 0% { opacity:; } 100% { opacity: .8; } } @keyframes proBackAction { 0{ op ...
- WPF中多个RadioButton绑定到一个属性
如图样: 在View中: <RadioButton IsChecked="{Binding Option, Converter={cvt:EnumToBooleanConverter} ...
- [OpenCV] Identify and Track Specific Object
Abstract—Augmented Reality (AR) has become increasingly popular in recent years and it has a widespr ...