[LNOI 2014] LCA

来源:互联网 发布:淘宝详情页一般多少钱 编辑:程序博客网 时间:2024/05/04 16:05

方案一:[a,b] 的lca和可以变成[1,a] 与 [1,b] 的答案和。

于是离线。


copied from wlc1121

方案二:

询问的是区间,于是想到莫队

树剖+线段树同上维护。

我自己没写过一个根号*两个log==QAQ留给底层优化大师去实现吧...


---------分割线---------

(隔壁q234rty说可以用欧拉序列去掉一个log)

(隔壁q234rty还说bzoj跑得快的应该是这样写的)

TMD被卡取膜卡了两天才卡出来

(还要感谢隔壁q234rty帮忙向bzoj要数据)

毕竟是氪金dalao~

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define rep(j,k,l) for (int j=k;j<=l;++j)#define red(j,k,l) for (int j=k;j>=l;--j)#define N 100005using namespace std;struct Qry{int k,x,i,ans;} Q[N*2];int n,T,cnt,to[N],ne[N],st[N],deep[N],fa[N],sz[N],son[N];int top[N],id[N],dfn[N],tr[4*N],fg[4*N];void add(int k,int l){to[++cnt]=l;ne[cnt]=st[k];st[k]=cnt;}void dfs1(int k,int ff){fa[k]=ff;deep[k]=deep[ff]+1;sz[k]=1;son[k]=0;for (int i=st[k];i;i=ne[i]){dfs1(to[i],k);sz[k]+=sz[to[i]];if (sz[to[i]]>sz[son[k]]) son[k]=to[i];}}void dfs2(int k,bool wlc1121){if (wlc1121) top[k]=top[fa[k]];else top[k]=k;id[k]=++cnt;dfn[cnt]=k;if (son[k]>0) dfs2(son[k],1);for (int i=st[k];i;i=ne[i])if (to[i]!=son[k]) dfs2(to[i],0);}bool cmp(const Qry &x,const Qry &y){return x.k<y.k;}bool Cmp(const Qry &x,const Qry &y){return x.i<y.i;}void Up(int k,int l,int r,int o,int p){if (l>p||r<o) return;if (l>=o&&r<=p){tr[k]+=r-l+1;fg[k]++;return;}if (fg[k]){tr[2*k]+=fg[k]*((l+r)/2-l+1);tr[2*k+1]+=fg[k]*(r-(l+r)/2);fg[2*k]+=fg[k];fg[2*k+1]+=fg[k];fg[k]=0;}Up(2*k,l,(l+r)/2,o,p);Up(2*k+1,(l+r)/2+1,r,o,p);tr[k]=tr[2*k]+tr[2*k+1];}void up(int x,int y){for (;top[x]!=top[y];x=fa[top[x]]){if (deep[top[x]]<deep[top[y]]) swap(x,y);Up(1,1,n,id[top[x]],id[x]);}if (deep[x]>deep[y]) swap(x,y);Up(1,1,n,id[x],id[y]);}int ask(int k,int l,int r,int o,int p){if (l>p||r<o) return 0;if (l>=o&&r<=p) return tr[k];if (fg[k]){tr[2*k]+=fg[k]*((l+r)/2-l+1);tr[2*k+1]+=fg[k]*(r-(l+r)/2);fg[2*k]+=fg[k];fg[2*k+1]+=fg[k];fg[k]=0;}return ask(2*k,l,(l+r)/2,o,p)+ask(2*k+1,(l+r)/2+1,r,o,p);}int qry(int x,int y){int ans=0;for (;top[x]!=top[y];x=fa[top[x]]){if (deep[top[x]]<deep[top[y]]) swap(x,y);ans=(ans+ask(1,1,n,id[top[x]],id[x]))%201314;}if (deep[x]>deep[y]) swap(x,y);ans=(ans+ask(1,1,n,id[x],id[y]))%201314;return ans;}int main(){scanf("%d%d",&n,&T);rep(i,2,n){int k;scanf("%d",&k);k++;add(k,i);}rep(i,1,T){int k,l,poi;scanf("%d%d%d",&k,&l,&poi);k++,l++,poi++;Q[2*i-1].k=k-1,Q[2*i].k=l;Q[2*i-1].x=Q[2*i].x=poi;Q[2*i-1].i=2*i;Q[2*i].i=i*2-1;}dfs1(1,1);cnt=0;dfs2(1,0);sort(Q+1,Q+T*2+1,cmp);int nw=1;while (nw<=2*T&&Q[nw].k==0) Q[nw].ans=0,nw++; rep(i,1,n){up(1,i);while (nw<=2*T&&Q[nw].k==i)Q[nw].ans=(qry(1,Q[nw].x))%201314,nw++;}sort(Q+1,Q+2*T+1,Cmp);rep(i,1,T) printf("%d\n",(Q[2*i-1].ans%201314-Q[2*i].ans%201314+201314)%201314);}


0 0
原创粉丝点击