首页 > 代码库 > AC日记——「SCOI2015」情报传递 LiBreOJ 2011
AC日记——「SCOI2015」情报传递 LiBreOJ 2011
#2011. 「SCOI2015」情报传递
思路:
可持久化树状数组模板;
代码:
#include <bits/stdc++.h>using namespace std;#define maxn 200005#define maxm maxn*100int deep[maxn],f[maxn],id[maxn],top[maxn],cnt,soot;int head[maxn],V[maxn],E[maxn],lar[maxn],size[maxn];int val[maxm],root[maxn],ch[maxm][2],tot,Tl,Tr,n,m,Ans;inline void in(int &now){ char Cget=getchar();now=0; while(Cget>‘9‘||Cget<‘0‘)Cget=getchar(); while(Cget>=‘0‘&&Cget<=‘9‘) { now=now*10+Cget-‘0‘; Cget=getchar(); }}void build(int &now,int l,int r){ now=++tot; if(l==r) return;int mid=l+r>>1; build(ch[now][0],l,mid); build(ch[now][1],mid+1,r);}void add(int &now,int pre,int l,int r,int to,int x){ now=++tot,val[now]=val[pre]+x; if(l==r) return;int mid=l+r>>1; if(to<=mid) add(ch[now][0],ch[pre][0],l,mid,to,x),ch[now][1]=ch[pre][1]; else add(ch[now][1],ch[pre][1],mid+1,r,to,x),ch[now][0]=ch[pre][0];}int lowbit(int x){ return x&(-x);}void add(int to1,int to2,int x){ while(to1<=n) add(root[to1],root[to1],1,m,to2,x),to1+=lowbit(to1);}void dfs1(int now){ deep[now]=deep[f[now]]+1,size[now]=1; for(int i=head[now];i;i=E[i]) { dfs1(V[i]),size[now]+=size[V[i]]; if(size[lar[now]]<size[V[i]]) lar[now]=V[i]; }}void dfs2(int now,int chain){ top[now]=chain,id[now]=++cnt; root[id[now]]=root[0]; if(lar[now]) { dfs2(lar[now],chain); for(int i=head[now];i;i=E[i]) { if(V[i]==lar[now]) continue; dfs2(V[i],V[i]); } }}int query(int now,int l,int r){ if(l>=Tl&&r<=Tr) return val[now]; int mid=l+r>>1,res=0; if(Tl<=mid) res+=query(ch[now][0],l,mid); if(Tr>mid) res+=query(ch[now][1],mid+1,r); return res;}int query(int l,int r){ l--;int res=0; while(r) res+=query(root[r],1,m),r-=lowbit(r); while(l) res-=query(root[l],1,m),l-=lowbit(l); return res;}int query(int x,int y,int tl,int tr){ int res=0;Tl=tl,Tr=tr; while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]]) res+=query(id[top[y]],id[y]),y=f[top[y]]; else res+=query(id[top[x]],id[x]),x=f[top[x]]; } if(deep[x]>deep[y]) swap(x,y); res+=query(id[x],id[y]); return res;}int lca(int x,int y){ while(top[x]!=top[y]) { if(deep[top[x]]>deep[top[y]]) x=f[top[x]]; else y=f[top[y]]; } return deep[x]<deep[y]?deep[x]:deep[y];}int main(){ freopen("data.txt","r",stdin); freopen("data.out","w",stdout); in(n);int op,u,v,c; for(int i=1;i<=n;i++) { in(f[i]); if(!f[i]) soot=i; else E[i]=head[f[i]],V[i]=i,head[f[i]]=i; } in(m); build(root[0],1,m),dfs1(soot),dfs2(soot,soot); for(int i=1;i<=m;i++) { in(op); if(op==2)in(u),add(id[u],i,1); else { in(u),in(v),in(c),Ans=deep[u]+deep[v]-2*lca(u,v)+1; printf("%d ",Ans); if(i-c-1>=1) printf("%d\n",query(u,v,1,i-c-1)); else printf("0\n"); } } return 0;}
AC日记——「SCOI2015」情报传递 LiBreOJ 2011
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。