首页 > 代码库 > BZOJ 4448 情报传递
BZOJ 4448 情报传递
注意到可以转化为静态。直接建树上主席树。
1A了赞。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxv 200500#define maxe 400500using namespace std;int n,g[maxv],nume=0,m,val[maxv],anc[maxv][21],dis[maxv],a,b,c,type,cnt=0,rt;int root[maxv],tot=0,ls[maxv<<4],rs[maxv<<4],sum[maxv<<4];struct edge{ int v,nxt;}e[maxe];struct query{ int x,y,id,c;}q[maxv];void addedge(int u,int v){ e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume;}void modify(int last,int &now,int left,int right,int pos){ now=++tot;sum[now]=sum[last]+1; if (left==right) return; ls[now]=ls[last];rs[now]=rs[last]; int mid=left+right>>1; if (pos<=mid) modify(ls[last],ls[now],left,mid,pos); else modify(rs[last],rs[now],mid+1,right,pos);}void dfs1(int x){ for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=anc[x][0]) { anc[v][0]=x;dis[v]=dis[x]+1; dfs1(v); } }}void dfs2(int x){ if (val[x]) modify(root[anc[x][0]],root[x],1,m,val[x]); else root[x]=root[anc[x][0]]; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=anc[x][0]) dfs2(v); }}void get_table(){ for (int e=1;e<=20;e++) for (int i=1;i<=n;i++) anc[i][e]=anc[anc[i][e-1]][e-1];}void build(int &now,int left,int right){ now=++tot;sum[now]=0; if (left==right) return; int mid=left+right>>1; build(ls[now],left,mid); build(rs[now],mid+1,right);}void build_tree(){ build(root[0],1,m); dfs2(rt);}int lca(int x,int y){ for (int e=20;e>=0;e--) { if ((dis[anc[x][e]]>=dis[y]) && (anc[x][e])) x=anc[x][e]; } if (x==y) return x; for (int e=20;e>=0;e--) { if (anc[x][e]!=anc[y][e]) { x=anc[x][e]; y=anc[y][e]; } } return anc[x][0];}int ask(int n1,int n2,int n3,int n4,int left,int right,int l,int r){ if (l>r) return 0; if ((left==l) && (right==r)) return sum[n3]+sum[n4]-sum[n1]-sum[n2]; int mid=left+right>>1; if (r<=mid) return ask(ls[n1],ls[n2],ls[n3],ls[n4],left,mid,l,r); else if (l>=mid+1) return ask(rs[n1],rs[n2],rs[n3],rs[n4],mid+1,right,l,r); else return ask(ls[n1],ls[n2],ls[n3],ls[n4],left,mid,l,mid)+ask(rs[n1],rs[n2],rs[n3],rs[n4],mid+1,right,mid+1,r);}void work(int now){ int x=q[now].x,y=q[now].y,id=q[now].id,c=q[now].c; if (dis[x]<dis[y]) swap(x,y); int t=lca(x,y); printf("%d %d\n",dis[x]+dis[y]-dis[t]-dis[anc[t][0]],ask(root[anc[t][0]],root[t],root[x],root[y],1,m,1,id-c-1));}int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&a); if (a) {addedge(a,i);addedge(i,a);} else rt=i; } dis[rt]=1;dfs1(rt);get_table(); scanf("%d",&m); for (int i=1;i<=m;i++) { scanf("%d",&type); if (type==1) { scanf("%d%d%d",&a,&b,&c); cnt++; q[cnt].x=a;q[cnt].y=b;q[cnt].id=i;q[cnt].c=c; } else { scanf("%d",&a); val[a]=i; } } build_tree(); for (int i=1;i<=cnt;i++) work(i); return 0;}
BZOJ 4448 情报传递
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。