bzoj3631: [JLOI2014]松鼠的新家
容易发现是树剖裸题。
然后毒瘤选手AKC表示好像可以用树上差分+LCA做。
就这样。水题。
诶那你咋没秒切。
妈也看错样例,然后画错图,接着就是理解错题目,最后R成傻逼之时发现我ST表开数组的顺序错了。。。
废物。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct node { int x,y,next; }a[610000];int len,last[310000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int Bin[30],f[310000][30]; int dep[310000]; void dfs(int x) { for(int i=1;i<=25;i++) if(dep[x]>=Bin[i])f[x][i]=f[f[x][i-1]][i-1]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=f[x][0]) { f[y][0]=x; dep[y]=dep[x]+1; dfs(y); } } } int LCA(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(int i=25;i>=0;i--) if(dep[x]-dep[y]>=Bin[i])x=f[x][i]; if(x==y)return x; for(int i=25;i>=0;i--) if(f[x][i]!=f[y][i]&&dep[x]>=Bin[i]) x=f[x][i], y=f[y][i]; return f[x][0]; } //------LCA--------- int ch[310000]; int tmp[310000]; void update(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=f[x][0]) { update(y); tmp[x]+=tmp[y]; } } } int main() { int n,x,y; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&ch[i]); len=0;memset(last,0,sizeof(last)); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); ins(x,y);ins(y,x); } //----sc---- Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2; dep[1]=1;f[1][0]=0;dfs(1); for(int i=1;i<=n-1;i++) { tmp[ch[i]]++; tmp[ch[i+1]]++; int lca=LCA(ch[i],ch[i+1]); tmp[lca]--; if(f[lca][0]!=0)tmp[f[lca][0]]--; } update(1); tmp[ch[1]]++; for(int i=1;i<=n;i++)printf("%d\n",tmp[i]-1); return 0; }
pain and happy in the cruel world.