zoukankan      html  css  js  c++  java
  • 洛谷P3258 [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

    题解:

    分明就是一道树链剖分模板题

    可是我还是写+调花了1个*时(55555……)

    好伤心啊,看来这些模板该再练练了,千万不能考试时又花这么长时间

    代码:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<string.h>
      4 using namespace std;
      5 
      6 const int MAXN = 300005;
      7 struct node{
      8     int v;
      9     node *next;
     10 }pool[2*MAXN],*h[MAXN];
     11 int cnt;
     12 int fa[MAXN],dep[MAXN],son[MAXN],sonnum[MAXN],vis[MAXN];
     13 int a[MAXN];
     14 
     15 void addedge(int u,int v){
     16     node *p=&pool[++cnt],*q=&pool[++cnt];
     17     p->v=v;p->next=h[u];h[u]=p;
     18     q->v=u;q->next=h[v];h[v]=q;     
     19 }
     20 
     21 void dfs(int u){
     22     int v;
     23     int maxson,maxnum=0;
     24     sonnum[u]=1;
     25     vis[u]=1;
     26     for(node *p=h[u];p;p=p->next)
     27         if(!vis[v=p->v]){
     28             dep[v]=dep[u]+1;
     29             fa[v]=u;
     30             dfs(v);
     31             sonnum[u]+=sonnum[v];
     32             if(sonnum[v]>maxnum) maxnum=sonnum[v],maxson=v; 
     33         }
     34     if(maxnum!=0) son[u]=maxson;
     35     else son[u]=-1;
     36 }
     37 
     38 int w[MAXN],rk[MAXN],t,top[MAXN];
     39 void dfs2(int u){
     40     int v;
     41     vis[u]=1;
     42     v=son[u];
     43     if(v!=-1){
     44         top[v]=top[u];
     45         rk[v]=++t;
     46         w[t]=v;
     47         dfs2(v);
     48     }
     49     for(node *p=h[u];p;p=p->next)
     50         if(!vis[v=p->v] && v!=son[u]){
     51             top[v]=v;
     52             rk[v]=++t;
     53             w[t]=v;
     54             dfs2(v);                
     55         }
     56 }
     57 
     58 struct tree{
     59     int v,lazy,l,r;
     60     tree *parent,*ch[2];       
     61 }d[MAXN*8],*root;
     62 int cnt1;
     63 void Build_Tree(tree *p,int l,int r){
     64     p->l=l;p->r=r;
     65     d[t].v=0;d[t].lazy=0;
     66     if(l==r) return;
     67     int mid=(l+r)/2;
     68     p->ch[0]=&d[++cnt1];p->ch[1]=&d[++cnt1];
     69     Build_Tree(p->ch[0],l,mid);
     70     Build_Tree(p->ch[1],mid+1,r);
     71 }
     72 void change(tree *p,int l,int r,int c){
     73     if(p->l==l && p->r==r){
     74         p->lazy+=c;
     75         return;           
     76     }
     77     if(p->lazy){
     78         p->ch[0]->lazy+=p->lazy;
     79         p->ch[1]->lazy+=p->lazy;
     80         p->lazy=0;            
     81     }
     82     if(l>=p->ch[1]->l) change(p->ch[1],l,r,c);
     83     else if(r<=p->ch[0]->r) change(p->ch[0],l,r,c);
     84     else{
     85         change(p->ch[0],l,p->ch[0]->r,c);
     86         change(p->ch[1],p->ch[1]->l,r,c);     
     87     }
     88 }
     89 int query(tree *p,int l,int r){
     90     if(p->l==l && p->r==r){
     91         return p->lazy;           
     92     }
     93     if(p->lazy){
     94         p->ch[0]->lazy+=p->lazy;
     95         p->ch[1]->lazy+=p->lazy;
     96         p->lazy=0;
     97     }
     98     if(l>=p->ch[1]->l) return query(p->ch[1],l,r);
     99     else if(r<=p->ch[0]->r) return query(p->ch[0],l,r);
    100     else{
    101         return query(p->ch[0],l,p->ch[0]->r)+query(p->ch[1],p->ch[1]->l,r);     
    102     }
    103 }
    104 
    105 void lca(int x,int y){
    106     int f1=top[x],f2=top[y];
    107     while(f1!=f2){
    108         if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
    109         change(root,rk[f1],rk[x],1);
    110         x=fa[f1];f1=top[x];             
    111     }
    112     if(dep[x]>dep[y]) swap(x,y);
    113     change(root,rk[x],rk[y],1);
    114 }
    115 int ans[MAXN];
    116 
    117 int main()
    118 {
    119     int i,j,n,x,y;
    120     scanf("%d",&n);
    121     for(i=1;i<=n;i++) scanf("%d",&a[i]);
    122     for(i=1;i<n;i++){
    123         scanf("%d%d",&x,&y);
    124         addedge(x,y);                 
    125     }
    126     
    127     root=&d[++cnt1];
    128     dep[1]=1;
    129     dfs(1);
    130     memset(vis,0,sizeof(vis));
    131     top[1]=1;rk[1]=1;t=1;w[1]=1;
    132     dfs2(1);
    133     Build_Tree(root,1,t);
    134     
    135     for(i=1;i<n;i++) lca(a[i],a[i+1]);
    136     
    137     for(i=1;i<=n;i++){
    138         x=query(root,i,i);
    139         if(w[i]!=a[1]) x--;
    140         ans[w[i]]=x;                 
    141     }
    142     for(i=1;i<=n;i++) printf("%d
    ",ans[i]);
    143 
    144     return 0;
    145 }
    View Code
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    深度学习之 TensorFlow(一):基础库包的安装
    爬取网易云音乐评论并使用词云展示
    MySQL学习笔记(一):查询
    【linux】查看linux系统版本信息(Oracle Linux、Centos Linux、Redhat Linux、Debian、Ubuntu)
    【php】PHP中Session ID的实现原理
    VMware安装VMwareTolls
    退耦、旁路电容
    SPI笔记
    旧板与IO板之间的连接
    S3C2440启动方式
  • 原文地址:https://www.cnblogs.com/lindalee/p/7706273.html
Copyright © 2011-2022 走看看