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]松鼠的新家的主要内容,如果未能解决你的问题,请参考以下文章

洛谷lca+树上差分P3258 [JLOI2014]松鼠的新家

P3258 [JLOI2014]松鼠的新家

Luogu P3258[JLOI2014]松鼠的新家

[JLOI2014]松鼠的新家 (树剖)

「JLOI2014」松鼠的新家

[Luogu 3258] JLOI2014 松鼠的新家