BZOJ2851 极限满月

来源:互联网 发布:linux运行sh文件指令 编辑:程序博客网 时间:2024/04/27 15:42

我们造一颗树,把B集合对应到树上,点i的B集合即为i到根的路径上的所有点,这样在构造点x的B集合的时候就相当于把所有A集合里的点取LCA,然后再LCA下面接上x

询问就相当于求询问点到根的路径并的长度,构虚树,每个点贡献为其深度减去其虚树上父亲的深度,不需要实际构造虚树,只要求出每个点的虚父亲即可

其实可以不用虚树,按dfn排序后所有点的dep减去每个相邻两点的lca的dep即可

有点卡常,加上读入优化就好了

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<algorithm>#include<iomanip>#include<vector>#include<stack>#include<queue>#include<map>#include<set>#include<bitset>using namespace std;#define MAXN 200010#define MAXM 1010#define ll long long#define INF 1000000000#define MOD 1000000007#define eps 1e-8char xB[1<<15],*xS=xB,*xT=xB;#define getc() (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)inline int read(){    char ch=getc();    int f=1,x=0;    while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getc();}    while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getc();}    return x*f;}struct vec{int to;int fro;};vec mp[MAXN];int tai[MAXN],cnt;int n;int fa[MAXN][20],dep[MAXN];int dfn[MAXN],tim;int m;int M;int t[MAXN];int st[MAXN],tp;inline void be(int x,int y){int t,j;mp[++cnt].to=y;mp[cnt].fro=tai[x];tai[x]=cnt;dep[y]=dep[x]+1;for(t=x,j=1;t;j++){fa[y][j]=t;t=fa[t][j];}}void dfs(int x){int i,y;dfn[x]=++tim;for(i=tai[x];i;i=mp[i].fro){y=mp[i].to;dfs(y);}}int lca(int x,int y){int i;if(dep[x]<dep[y]){swap(x,y);}for(i=19;i;i--){if(dep[fa[x][i]]>=dep[y]){x=fa[x][i];}}for(i=19;i;i--){if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return x==y?x:fa[x][1];}bool cmp(int x,int y){return dfn[x]<dfn[y];}int main(){int i,x,y;n=read();dep[n+1]=1;for(i=1;i<=n;i++){x=read();int l;if(x){l=read();x--;while(x--){y=read();l=lca(y,l);}}else{l=n+1;}be(l,i);}dfs(n+1);m=read();while(m--){M=read();for(i=1;i<=M;i++){t[i]=read();}sort(t+1,t+M+1,cmp);st[tp=1]=n+1;int ans=0;for(i=1;i<=M;i++){int l=lca(t[i],st[tp]);while(dep[st[tp]]>dep[l]){if(dep[st[tp-1]]>dep[l]){ans+=dep[st[tp]]-dep[st[tp-1]];}else{ans+=dep[st[tp]]-dep[l];}tp--;}if(l!=st[tp]){st[++tp]=l;}st[++tp]=t[i];}while(tp>1){ans+=dep[st[tp]]-dep[st[tp-1]];tp--;}printf("%d\n",ans);}return 0;}/*701 11 11 22 2 302 2 632 2 32 3 52 4 5*/


0 0
原创粉丝点击