P3258 [JLOI2014]松鼠的新家
Posted WeiAR
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3258 [JLOI2014]松鼠的新家相关的知识,希望对你有一定的参考价值。
P3258 [JLOI2014]松鼠的新家
倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<set> 8 #include<map> 9 #include<stack> 10 #include<cstring> 11 #define inf 2147483647 12 #define For(i,a,b) for(register int i=a;i<=b;i++) 13 #define p(a) putchar(a) 14 #define g() getchar() 15 //by war 16 //2017.11.8 17 using namespace std; 18 int f[300010][20]; 19 int a[300010],b[300010]; 20 int deep[300010]; 21 int change[300010]; 22 bool vis[300010]; 23 int lca; 24 int x,y; 25 int n; 26 struct node 27 { 28 int n; 29 node *next; 30 }*e[600010]; 31 32 inline void in(register int &x) 33 { 34 int y=1; 35 char c=g();x=0; 36 while(c<‘0‘||c>‘9‘) 37 { 38 if(c==‘-‘) 39 y=-1; 40 c=g(); 41 } 42 while(c<=‘9‘&&c>=‘0‘)x=(x<<1)+(x<<3)+c-‘0‘,c=g(); 43 x*=y; 44 } 45 inline void o(register int x) 46 { 47 if(x<0) 48 { 49 p(‘-‘); 50 x=-x; 51 } 52 if(x>9)o(x/10); 53 p(x%10+‘0‘); 54 } 55 56 inline void push(register int x,register int y) 57 { 58 node *p; 59 p=new node(); 60 p->n=y; 61 if(e[x]==NULL) 62 e[x]=p; 63 else 64 { 65 p->next=e[x]->next; 66 e[x]->next=p; 67 } 68 } 69 70 inline void build(register int now) 71 { 72 deep[now]=deep[f[now][0]]+1; 73 for(register int i=1;(1<<i)<=n;i++) 74 f[now][i]=f[f[now][i-1]][i-1]; 75 for(node *i=e[now];i!=NULL;i=i->next) 76 { 77 if(f[now][0]!=i->n) 78 { 79 f[i->n][0]=now; 80 build(i->n); 81 } 82 } 83 } 84 85 inline int query(register int x,register int y) 86 { 87 if(deep[x]<deep[y]) 88 swap(x,y); 89 int c=deep[x]-deep[y]; 90 for(register int i=0;(1<<i)<=c;i++) 91 if((1<<i)&c) 92 x=f[x][i]; 93 if(x==y) 94 return x; 95 for(register int i=log2(deep[x]);i>=0;i--) 96 { 97 if(f[x][i]!=f[y][i]) 98 { 99 x=f[x][i]; 100 y=f[y][i]; 101 } 102 } 103 return f[x][0]; 104 } 105 106 int dfs(int now) 107 { 108 if(vis[now]) 109 return b[now]; 110 vis[now]=true; 111 for(node *i=e[now];i!=NULL;i=i->next) 112 if(!vis[i->n]) 113 { 114 x=dfs(i->n); 115 b[now]+=x; 116 } 117 return b[now]; 118 } 119 120 int main() 121 { 122 // freopen("t.in","r",stdin); 123 // freopen("t2.out","w",stdout); 124 in(n); 125 For(i,1,n) 126 in(a[i]); 127 For(i,1,n-1) 128 { 129 in(x),in(y); 130 push(x,y); 131 push(y,x); 132 } 133 // f[0][0]=0; 134 build(1); 135 For(i,1,n-1) 136 { 137 x=a[i]; 138 y=a[i+1]; 139 lca=query(x,y); 140 change[x]++; 141 change[y]++; 142 change[lca]--; 143 change[f[lca][0]]--; 144 } 145 For(i,1,n) 146 b[i]=change[i]; 147 b[1]=dfs(1); 148 For(i,2,n) 149 b[a[i]]--; 150 For(i,1,n) 151 o(b[i]),p(‘\n‘); 152 return 0; 153 }
以上是关于P3258 [JLOI2014]松鼠的新家的主要内容,如果未能解决你的问题,请参考以下文章