zoukankan      html  css  js  c++  java
  • [JLOI2014]松鼠的新家

    题目描述

    松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。

    松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

    维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。

    因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

    输入输出格式

    输入格式:

    第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

    输出格式:

    一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。

    输入输出样例

    输入样例#1:
    5
    1 4 5 3 2
    1 2
    2 4
    2 3
    4 5
    输出样例#1:
    1
    2
    1
    2
    1

    说明

    2<= n <=300000

    树上差分:

    和区间[l,r]+1的方法d[x]++,d[y+1]--差不多

    拓展到树上,x到y+1,显然可以树链剖分,但树上差分更快

    方法d[x]++,d[y]++,d[Lca]--,d[fa(Lca)]--

    Lca减1是因为重复

    还有最后求完和后,要把每一条路的终点-1,因为算了2次

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 struct Node
      7 {
      8   int next,to;
      9 }edge[600001];
     10 int num,head[300001],dep[300001],fa[300001][19],d[300001],a[300001],n;
     11 void add(int u,int v)
     12 {
     13   num++;
     14   edge[num].next=head[u];
     15   head[u]=num;
     16   edge[num].to=v;
     17 }
     18 void dfs(int x,int pa)
     19 {int i;
     20   dep[x]=dep[pa]+1;
     21   for (i=1;i<=18;i++)
     22     {
     23       fa[x][i]=fa[fa[x][i-1]][i-1];
     24     }
     25   for (i=head[x];i;i=edge[i].next)
     26     {int v=edge[i].to;
     27       if (v!=pa)
     28     {
     29       fa[v][0]=x;
     30       dfs(v,x);
     31     }
     32     }
     33 }
     34 void dfs_sum(int x,int pa)
     35 {int i;
     36    for (i=head[x];i;i=edge[i].next)
     37     {int v=edge[i].to;
     38       if (v!=pa)
     39     {
     40       dfs_sum(v,x);
     41       d[x]+=d[v];
     42     }
     43     }
     44 }
     45 int LCA(int x,int y)
     46 {int i;
     47   if (dep[x]<dep[y]) swap(x,y);
     48   for (i=18;i>=0;i--)
     49     if ((1<<i)<=dep[x]-dep[y])
     50       {
     51     x=fa[x][i];
     52       }
     53   if (x==y) return x;
     54   if (x!=y)
     55     {
     56       for (i=18;i>=0;i--)
     57     {
     58       if (fa[x][i]!=fa[y][i])
     59         {
     60           x=fa[x][i];
     61           y=fa[y][i];
     62         }
     63     }
     64       x=fa[x][0];
     65       y=fa[y][0];
     66     }
     67   return x;
     68 }
     69 int main()
     70 {int i,x,y;
     71   cin>>n;
     72   for (i=1;i<=n;i++)
     73     {
     74       scanf("%d",&a[i]);
     75     }
     76   for (i=1;i<=n-1;i++)
     77     {
     78       scanf("%d%d",&x,&y);
     79       add(x,y);
     80       add(y,x);
     81     }
     82   dfs(1,0);
     83   for (i=2;i<=n;i++)
     84     {
     85       int x=LCA(a[i-1],a[i]);
     86       d[a[i-1]]++;
     87       d[a[i]]++;
     88       d[x]--;
     89       d[fa[x][0]]--;
     90     }
     91   dfs_sum(1,0);
     92   for (i=2;i<=n;i++)
     93     {
     94       d[a[i]]--;
     95     }
     96   for (i=1;i<=n;i++)
     97     {
     98       printf("%d
    ",d[i]);
     99     }
    100 }
  • 相关阅读:
    csp 通信网络
    从客户端(content="xxxxx")中检测到有潜在危险的 Request.Form 值——较合理解决方案
    HttpUtility.HtmlEncode 方法
    web程序防止攻击的一些资料——整理
    memcached——学习
    VS2015 无法启动IIS Express Web服务器
    文件上传——资料收集
    水晶报表-需要安装软件
    web安全漏洞相关
    javascript一个在网页上画线的库
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7457889.html
Copyright © 2011-2022 走看看