zoukankan      html  css  js  c++  java
  • bzoj3631 松鼠的新家 树链poi~分

    填坑填坑……链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3631

    题意:每走一遍一个节点就要增加一次计数器,最后到达终点不需增加,输出按顺序游历整棵树每个节点计数器的值。

    就是裸的树链剖分……唯一的坑点

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 const int maxn=300005;
      7 struct node
      8 {
      9     int from,to,next;
     10 }edge[maxn<<1];
     11 int head[maxn],tot;
     12 void addedge(int u,int v)
     13 {
     14     edge[++tot]=(node){u,v,head[u]};head[u]=tot;
     15 }
     16 int n,ord[maxn],top[maxn],dep[maxn],pos[maxn],id[maxn],cnt,son[maxn],siz[maxn],pa[maxn];
     17 void dfs1(int root,int fa,int deep)
     18 {
     19     son[root]=0;dep[root]=deep;siz[root]=1;
     20     for(int i=head[root];i;i=edge[i].next)
     21     {
     22         int v=edge[i].to;
     23         if(pa[root]!=v)
     24         {
     25             pa[v]=root;
     26             dfs1(v,root,deep+1);
     27             siz[root]+=siz[v];
     28             if(siz[v]>siz[son[root]])son[root]=v;
     29         }
     30     }
     31 }
     32 void dfs2(int root,int tp)
     33 {
     34     top[root]=tp;pos[++cnt]=root;id[root]=cnt;
     35     if(son[root])dfs2(son[root],tp);
     36     for(int i=head[root];i;i=edge[i].next)
     37     {
     38         int v=edge[i].to;
     39         if(v!=pa[root]&&v!=son[root])dfs2(v,v);
     40     }
     41 }
     42 #define mid ((l+r)>>1)
     43 #define lc root<<1
     44 #define rc root<<1|1
     45 #define lson lc,l,mid
     46 #define rson rc,mid+1,r
     47 int sm[maxn<<2],st[maxn<<2];
     48 void pushdown(int root,int l,int r)
     49 {
     50     if(st[root])
     51     {
     52         st[lc]+=st[root];st[rc]+=st[root];
     53         sm[lc]+=st[root]*(mid-l+1);sm[rc]+=st[root]*(r-mid);
     54         st[root]=0;
     55     }
     56 }
     57 void update(int root)
     58 {
     59     sm[root]=sm[lc]+sm[rc];
     60 }
     61 void modify(int root,int l,int r,int L,int R)
     62 {
     63     if(L<=l&&r<=R)
     64     {
     65         sm[root]+=r-l+1;st[root]++;
     66         return;
     67     }
     68     pushdown(root,l,r);
     69     if(L<=mid)modify(lson,L,R);if(R>mid)modify(rson,L,R);
     70     update(root);
     71 }
     72 void modify(int x,int y)
     73 {
     74     int fx=top[x],fy=top[y];
     75     while(fx!=fy)
     76     {
     77         if(dep[fx]<dep[fy])swap(x,y),swap(fx,fy);
     78         modify(1,1,n,id[fx],id[x]);
     79         x=pa[fx];fx=top[x];
     80     }
     81     if(dep[x]>dep[y])swap(x,y);
     82     modify(1,1,n,id[x],id[y]);
     83 }
     84 int query(int root,int l,int r,int pos)
     85 {
     86     if(l==r)return sm[root];
     87     pushdown(root,l,r);
     88     if(pos<=mid)return query(lson,pos);
     89     else return query(rson,pos);
     90 }
     91 int haha()
     92 {
     93     scanf("%d",&n);
     94     for(int i=1;i<=n;i++)scanf("%d",&ord[i]);
     95     for(int i=1;i<n;i++)
     96     {
     97         int x,y;scanf("%d%d",&x,&y);
     98         addedge(x,y);addedge(y,x);
     99     }
    100     dfs1(1,-1,1);dfs2(1,1);
    101     for(int i=1;i<n;i++)modify(ord[i],ord[i+1]);
    102     for(int i=1;i<=n;i++)
    103     {
    104         int val=query(1,1,n,id[i]);
    105         if(i!=ord[1])val--;
    106         printf("%d
    ",val);
    107     }
    108 }
    109 int sb=haha();
    110 int main(){;}
    bzoj3631

    可能就是除了开头的那个点每个点最后结果都要$-1$s,因为中间那些点加了两次,最后那个点到达后不再计数。

  • 相关阅读:
    22、闭包与继承
    合并两个有序链表
    7. 整数反转
    Linux grep命令
    认识与学习BASH
    微信支付-H5网页支付开通流程
    解决 Qt5 报错 This application failed to start because it could not find or load the Qt platform plugin
    Linux 创建交换分区扩展虚拟内存
    Linux 逻辑卷管理LVM
    Linux的文件权限
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7354832.html
Copyright © 2011-2022 走看看