zoukankan      html  css  js  c++  java
  • 权值线段树-动态开点-合并(P4556 [Vani有约会]雨天的尾巴

    题意:https://www.luogu.com.cn/problem/P4556

    树链加数,问你每个节点最多的是哪个数。

    思路:

    树链加数很容易想到差分。

    从下往上用权值线段树合并即可,直接用pushup把答案存在树根即可,不用每次查询最多的数

      1 struct EDGE
      2 {
      3     int to,next;
      4 }edge[N];
      5 int tot;
      6 int head[N];
      7 void Init(int n)
      8 {
      9     tot=0;
     10     for(int i=0;i<=n;++i)
     11         head[i]=0;
     12 }
     13 void add(int from,int to)
     14 {
     15     ++tot;
     16     edge[tot].to=to;
     17     edge[tot].next=head[from];
     18     head[from]=tot;
     19 }//for(int i=head[x];i;i=edge[i].next)
     20 
     21 int f[N][25],d[N];
     22 void update(int x) {//用之前记得设f[x][0]
     23     for (int i=1; i<=24; i++)
     24         f[x][i]=f[f[x][i-1]][i-1];
     25     return ;
     26 }
     27 int LCA(int a, int b) {
     28     if (d[a]>d[b]) swap(a, b);
     29     int h=d[b]-d[a];
     30     for (int i=0; (1<<i)<=h; i++)
     31         if ((1<<i)&h) b=f[b][i];
     32     if (a!=b) {
     33         for (int i=24; i>=0; i--)
     34             if (f[a][i]!=f[b][i]) a=f[a][i], b=f[b][i];
     35         a=f[a][0];
     36     }
     37     return a;
     38 }
     39 void dfs1(int u,int fa){
     40     f[u][0]=fa;
     41     d[u]=d[fa]+1;
     42     update(u);
     43     for(int i=head[u];i;i=edge[i].next)
     44     {
     45         int to=edge[i].to;
     46         if(to==fa)continue;
     47         dfs1(to,u);
     48     }
     49 }
     50 
     51 int top;
     52 struct node
     53 {
     54     int sz,ans,lson,rson;
     55 }tr[N];
     56 int rt[N],R=100005;
     57 int res[N];
     58 void up(int x){
     59     if(tr[tr[x].lson].sz>=tr[tr[x].rson].sz)tr[x].ans=tr[tr[x].lson].ans,tr[x].sz=tr[tr[x].lson].sz;
     60     else tr[x].ans=tr[tr[x].rson].ans,tr[x].sz=tr[tr[x].rson].sz;
     61 }
     62 void insert(int &x,int l,int r,int pos,int val)
     63 {
     64     if(!x)x=++top,tr[top]=node();
     65     if(l==r){
     66         tr[x].sz+=val;
     67         tr[x].ans=l;
     68         return;
     69     }
     70     int mid=l+r>>1;
     71     if(pos<=mid)insert(tr[x].lson,l,mid,pos,val);
     72     else insert(tr[x].rson,mid+1,r,pos,val);
     73     up(x);
     74 }
     75 int n,m;
     76 int merge(int x,int y,int l,int r)
     77 {
     78     if(!x||!y)return x+y;
     79     if(l==r){
     80         tr[x].sz+=tr[y].sz;
     81         return x;
     82     }
     83     int mid=l+r>>1;
     84     tr[x].lson=merge(tr[x].lson,tr[y].lson,l,mid);
     85     tr[x].rson=merge(tr[x].rson,tr[y].rson,mid+1,r);
     86     up(x);
     87     return x;
     88 }
     89 void dfs(int u,int fa)
     90 {
     91     for(int i=head[u];i;i=edge[i].next)
     92     {
     93         int to=edge[i].to;
     94         if(to==fa)continue;
     95         dfs(to,u);
     96         rt[u]=merge(rt[u],rt[to],1,R);
     97     }
     98     if(tr[u].sz)res[u]=tr[rt[u]].ans;
     99 }
    100 
    101 signed main()
    102 {
    103     sc("%d%d",&n,&m);
    104     for(int i=1;i<n;++i)
    105     {
    106         int u,v;
    107         sc("%d%d",&u,&v);
    108         add(u,v);
    109         add(v,u);
    110     }
    111     dfs1(1,0);
    112     top=0;
    113     for(int i=1;i<=n;++i)rt[i]=++top;
    114     for(int i=1;i<=m;++i)
    115     {
    116         int u,v,val;
    117         sc("%d%d%d",&u,&v,&val);
    118         int lca=LCA(u,v);
    119         insert(rt[u],1,R,val,1);
    120         insert(rt[v],1,R,val,1);
    121         insert(rt[lca],1,R,val,-1);
    122         if(f[lca][0])
    123             insert(rt[f[lca][0]],1,R,val,-1);
    124     }
    125     dfs(1,0);
    126     for(int i=1;i<=n;++i)
    127         pr("%d
    ",res[i]);
    128     return 0;
    129 }
  • 相关阅读:
    linux学习笔记---grep
    node.js读取到的文件列表
    node 按行读取文件
    NodeJS遍历文件生产文件列表
    常用linux命令行
    2017/11/13
    Linux下输出 excel文件
    位映射对大数据的排重
    算法中的渐进记号
    KMP算法原理
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/13192035.html
Copyright © 2011-2022 走看看