hdu4718 The LCIS on the Tree(树链剖分)
2017-09-10 22:33
441 查看
有向的合并区间。看好了是求最长连续上升子序列,并非最长上升子序列。。。这样就可以拿线段树维护,左端点的值,右端点的值,左端点正着最多几个,右端点正着最多几个,左端点倒着最多几个,右端点倒着最多几个,正着最优几个,倒着最优几个,还要看好方向,真是麻烦呢。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 100010 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,tt,m,a ,w ,h ,num=0,fa ,dep ,son ,size ,top ,id ,dfn=0; struct edge{ int to,next; }data ; struct node{ in 12bd3 t l,r,len,ls,rs,ans1,ans2,ls2,rs2;//ans1--l->r ans2--r->l node(){ l=r=len=ls=rs=ans1=ans2=ls2=rs2=0; } node operator+(node b){ node res; if(ans1==0) return b; if(b.ans1==0) return *this; res.l=l;res.r=b.r;res.ls=ls;res.rs=b.rs; res.ls2=ls2;res.rs2=b.rs2;res.len=len+b.len; res.ans1=max(ans1,b.ans1);res.ans2=max(ans2,b.ans2); if(r<b.l){ res.ans1=max(res.ans1,rs+b.ls); res.ls+= ls==len?b.ls:0; res.rs+= b.rs==b.len?rs:0; } if(b.l<r){ res.ans2=max(res.ans2,rs2+b.ls2); res.ls2+= ls2==len?b.ls2:0; res.rs2+= b.rs2==b.len?rs2:0; } return res; } }tree[N<<2]; void dfs1(int x){ size[x]=1; for(int i=h[x];i;i=data[i].next){ int y=data[i].to; fa[y]=x;dep[y]=dep[x]+1;dfs1(y);size[x]+=size[y]; if(size[y]>size[son[x]]) son[x]=y; } } void dfs2(int x,int tp){ id[x]=++dfn;top[x]=tp;w[dfn]=a[x]; if(son[x]) dfs2(son[x],tp); for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(y==son[x]) continue;dfs2(y,y); } } void build(int p,int l,int r){ if(l==r){ tree[p].l=tree[p].r=w[l]; tree[p].ls=tree[p].rs=tree[p].ls2=tree[p].rs2=1; tree[p].ans1=tree[p].ans2=tree[p].len=1;return; } int mid=l+r>>1; build(p<<1,l,mid);build(p<<1|1,mid+1,r); tree[p]=tree[p<<1]+tree[p<<1|1]; } node query(int p,int l,int r,int x,int y){ if(x<=l&&r<=y) return tree[p]; int mid=l+r>>1;node res; if(x<=mid) res=query(p<<1,l,mid,x,y)+res; if(y>mid) res=res+query(p<<1|1,mid+1,r,x,y); return res; } int solve(int x,int y){ node ansl,ansr;int res=0; while(top[x]!=top[y]){ if(dep[top[x]]>dep[top[y]]){ ansl=query(1,1,n,id[top[x]],id[x])+ansl; x=fa[top[x]]; } else{ ansr=query(1,1,n,id[top[y]],id[y])+ansr; y=fa[top[y]]; } } if(id[x]<id[y]){ ansr=query(1,1,n,id[x],id[y])+ansr; res=max(ansl.ans2,ansr.ans1); if(ansl.l<ansr.l) res=max(res,ansl.ls2+ansr.ls); } else{ ansl=query(1,1,n,id[y],id[x])+ansl; res=max(ansl.ans2,ansr.ans1); if(ansl.l<ansr.l) res=max(res,ansl.ls2+ansr.ls); } return res; } int main(){ // freopen("a.in","r",stdin); tt=read(); for(int ttt=1;ttt<=tt;++ttt){ if(ttt!=1) puts(""); printf("Case #%d:\n",ttt); memset(h,0,sizeof(h));memset(fa,0,sizeof(fa)); memset(son,0,sizeof(son));num=dfn=0; n=read();for(int i=1;i<=n;++i) a[i]=read(); for(int i=2;i<=n;++i){ int x=read();data[++num].to=i;data[num].next=h[x];h[x]=num; }dep[1]=1;dfs1(1);dfs2(1,1);build(1,1,n);m=read(); while(m--){ int x=read(),y=read();printf("%d\n",solve(x,y)); } } return 0; }
相关文章推荐
- HDU 4718 The LCIS on the Tree (树链剖分 + 线段树区间合并)
- hdu_4718_The LCIS on the Tree(树链剖分+线段树合并)
- 【树链剖分】 HDOJ 4718 The LCIS on the Tree
- hdu_4718_The LCIS on the Tree(树链剖分+线段树合并)
- HDU 4718 The LCIS on the Tree (树链剖分+线段树区间合并)
- hdu-4718:The LCIS on the Tree(树链剖分+区间合并)
- HDU 4718 The LCIS on the Tree(树链剖分)
- HDU4718 The LCIS on the Tree(LCT)
- 【HDOJ】4718 The LCIS on the Tree 树链剖分
- 【HDU 4718】 The LCIS on the Tree 【树链剖分+线段树合并】
- HDU 4718 The LCIS on the Tree (动态树LCT)
- spoj 375 Query on the tree [树链剖分]
- lca(HDU 4718,The LCIS on the Tree)
- hdu 4912 Paths on the tree(树链剖分+贪心)
- hdu 4718 The LCIS on the Tree
- HDU 4718 The LCIS on the Tree 树上路径倍增
- Hdu 4718 The LCIS on the Tree 动态树 LCT
- HDU 4718 The LCIS on the Tree(树链剖分+线段树)
- HDU 4718 The LCIS on the Tree
- 【ZJU】3863 Paths on the Tree 【浙大2015年4月校赛D题】 树分治