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

    bzoj3631[JLOI2014]松鼠的新家

    题意:

    给个n点树,再给个节点的游览顺序,每经过一个节点(包括上一个游览的点到下一个游览的点路径上的点)就可以从这个节点拿走一个糖,问所有节点一开始要放几个糖。最后到达的节点不用糖。n≤300000

    题解:

    链剖将树链排成一列,然后用数组区间加的方式(即在数组区间左端点位置增加值,数组区间右端点+1位置增加这个值的相反数,最后扫一遍a[i]+=a[i-1])累计糖果数。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 300100
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 using namespace std;
     7 
     8 inline int read(){
     9     char ch=getchar(); int f=1,x=0;
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    11     return x*f;
    12 }
    13 struct e{int t,n;}; e es[maxn*2]; int g[maxn],ess;
    14 void pe(int f,int t){
    15     es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess;
    16 }
    17 void init(){ess=0; memset(g,0,sizeof(g));}
    18 int n,fa[maxn],dep[maxn],go[maxn],pos[maxn],top[maxn],sz[maxn],sm[maxn],tot;
    19 void dfs1(int x,int f){
    20     sz[x]=1; 
    21     for(int i=g[x];i;i=es[i].n)if(es[i].t!=f){
    22         dep[es[i].t]=dep[x]+1; fa[es[i].t]=x;
    23         dfs1(es[i].t,x); sz[x]+=sz[es[i].t];
    24     }
    25 }
    26 void dfs2(int x,int f,int tp){
    27     pos[x]=++tot; top[x]=tp; int mx=0;
    28     for(int i=g[x];i;i=es[i].n)if(es[i].t!=f){
    29         if(!mx||sz[mx]<sz[es[i].t])mx=es[i].t;
    30     }
    31     if(!mx)return; dfs2(mx,x,tp);
    32     for(int i=g[x];i;i=es[i].n)if(es[i].t!=f&&es[i].t!=mx){
    33         dfs2(es[i].t,x,es[i].t);
    34     }
    35 }
    36 void lca(int x,int y){
    37     for(;top[x]!=top[y];sm[pos[top[x]]]++,sm[pos[x]+1]--,x=fa[top[x]])
    38         if(dep[top[x]]<dep[top[y]])swap(x,y);
    39     if(dep[x]>dep[y])swap(x,y); sm[pos[x]]++,sm[pos[y]+1]--;
    40 }
    41 int main(){
    42     n=read(); inc(i,1,n)go[i]=read(); init();
    43     inc(i,1,n-1){int a=read(),b=read(); pe(a,b);}
    44     dep[1]=0; fa[1]=0; tot=0; dfs1(1,0); dfs2(1,0,1);
    45     inc(i,1,n){
    46         if(i==1){sm[pos[go[i]]]++; sm[pos[go[i]]+1]--; continue;}
    47         sm[pos[go[i-1]]]--; sm[pos[go[i-1]]+1]++; lca(go[i-1],go[i]);
    48         if(i==n){sm[pos[go[i]]]--; sm[pos[go[i]]+1]++;}
    49     }
    50     inc(i,1,tot)sm[i]+=sm[i-1]; inc(i,1,n)printf("%d
    ",sm[pos[i]]);
    51     return 0;
    52 }

    20160610

  • 相关阅读:
    团队冲刺第四天
    团队冲刺第三天
    找1的个数
    寻找最水之王
    最优价格买书
    团队冲刺第二天
    团队冲刺第一天
    团队开发项目特点
    第一阶段冲刺站立会议报告——4
    第一阶段冲刺站立会议报告——3
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5778209.html
Copyright © 2011-2022 走看看