zoukankan      html  css  js  c++  java
  • HDU5029--Relief grain (树链剖分+线段树 )

    题意:n个点构成的无根树,m次操作, 对于操作 x y z, 表示 xy 路径上的 每个点 加一个 z 数字,可重复加。最后输出每个点 加的次数最多的那个数字,如果没有输出0.

    赤裸裸的树链剖分,可是剖分之后 怎么用线段树维护每个点加的数字的次数呢。这里用到的思想类似于2014年上海网络赛的一道题。HDU5044,假如[x,y]这个区间上所有的点加上数字z,可以用两个标记 vec[x] + z,vec[y+1] -c。HDU上C++提交竟然爆栈,不过G++还是顺利ac了。具体见代码

      1 #include <cstdio>
      2 #include <vector>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <algorithm>
      6 using namespace std;
      7 const int maxn = 1e5+10;
      8 int siz[maxn],dep[maxn],son[maxn],fa[maxn];
      9 struct
     10 {
     11     int to,next;
     12 }e[maxn<<1];
     13 int tot,head[maxn];
     14 void add_edge(int x,int y)
     15 {
     16     e[tot].to = y;
     17     e[tot].next = head[x];
     18     head[x] = tot++;
     19 }
     20 void dfs(int r)
     21 {
     22     son[r] = 0;
     23     siz[r] = 1;
     24     for (int i = head[r]; ~i; i = e[i].next)
     25     {
     26         int u = e[i].to;
     27         if (fa[r] != u)
     28         {
     29             dep[u] = dep[r] + 1;
     30             fa[u] = r;
     31             dfs(u);
     32             if (siz[u] > siz[son[r]])
     33                 son[r] = u;
     34             siz[r] += siz[u];
     35         }
     36     }
     37 }
     38 int top[maxn],pos[maxn],fp[maxn],idx;
     39 void build(int r,int father)
     40 {
     41     pos[r] = ++idx;                           //记录每一个点 对应的位置
     42     fp[pos[r]] = r;                          //记录每一个位置对应的点
     43     top[r] = father;
     44     if (son[r] > 0)
     45         build(son[r],top[r]);
     46     for (int i = head[r]; ~i; i = e[i].next)
     47     {
     48         if (fa[r] != e[i].to && son[r] != e[i].to)
     49             build(e[i].to,e[i].to);
     50     }
     51 }
     52 vector<int>vec[maxn];
     53 void update(int x,int y,int v)
     54 {
     55     int fx = top[x];
     56     int fy = top[y];
     57     while (fx != fy)
     58     {
     59         if (dep[fx] < dep[fy])
     60         {
     61             swap(x,y),swap(fx,fy);
     62         }
     63         vec[pos[fx]].push_back(v);                       //有点类似于树状数组区间更新单点查询,
     64         vec[pos[x] + 1].push_back(-v);
     65         x = fa[fx];
     66         fx = top[x];
     67     }
     68     if (dep[x] > dep[y])
     69         swap(x,y);
     70     vec[pos[x]].push_back(v);
     71     vec[pos[y] + 1].push_back(-v);
     72 }
     73 
     74 int n,m,seg[maxn<<2],max_pos[maxn<<2];         //max_pos为最大值在原始数组中的位置
     75 void init()
     76 {
     77     int root = (1+n)/2;
     78     idx = tot = 0;
     79     dep[root] = fa[root] = 0;
     80     memset(head,-1,sizeof(head));
     81     memset(siz,0,sizeof(siz));
     82     memset(seg,0,sizeof(seg));
     83     memset(max_pos,0,sizeof(max_pos));
     84     for (int i = 0; i < n - 1; i++)
     85     {
     86         int u,v;
     87         scanf ("%d%d",&u,&v);
     88         add_edge(u,v);
     89         add_edge(v,u);
     90     }
     91     dfs(root);
     92     build(root,root);
     93     for (int i = 1; i <= n; i++)
     94         vec[i].clear();
     95     for (int i = 0; i < m; i++)
     96     {
     97         int x,y,v;
     98         scanf ("%d%d%d",&x,&y,&v);
     99         update(x,y,v);
    100     }
    101 }
    102 void update(int l,int r,int pos,int x,int val)
    103 {
    104     if (l == r)
    105     {
    106         seg[pos] += val;
    107         if (seg[pos] > 0)
    108             max_pos[pos] = l;
    109         else
    110             max_pos[pos] = 0;
    111         return;
    112     }
    113     int mid = (l + r) >> 1;
    114     if (x <= mid)
    115         update(l,mid,pos<<1,x,val);
    116     else
    117         update(mid+1,r,pos<<1|1,x,val);
    118     if (seg[pos<<1] >= seg[pos<<1|1])
    119     {
    120         seg[pos] = seg[pos<<1];
    121         max_pos[pos] = max_pos[pos<<1];
    122     }
    123     else
    124     {
    125         seg[pos] = seg[pos<<1|1];
    126         max_pos[pos] = max_pos[pos<<1|1];
    127     }
    128 }
    129 int ans[maxn];
    130 void solve()
    131 {
    132     for (int i = 1; i <= n; i++)
    133     {
    134         for (unsigned int j = 0; j < vec[i].size(); j++)
    135         {
    136             if (vec[i][j] > 0)
    137                 update(1,maxn,1,vec[i][j],1);
    138             else
    139                 update(1,maxn,1,-vec[i][j],-1);
    140         }
    141         ans[fp[i]] = max_pos[1];
    142     }
    143     for (int i = 1; i <= n; i++)
    144         printf("%d
    ",ans[i]);
    145 
    146 }
    147 int main(void)
    148 {
    149     #ifndef ONLINE_JUDGE
    150         freopen("in.txt","r",stdin);
    151     #endif
    152     while (~scanf ("%d%d",&n,&m))
    153     {
    154         if ((n == 0) && (m == 0))
    155             break;
    156         init();
    157         solve();
    158     }
    159     return 0;
    160 }
  • 相关阅读:
    8. Django系列之上传文件与下载-djang为服务端,requests为客户端
    机器学习入门15
    机器学习入门14
    机器学习入门13
    机器学习入门12
    ML
    AI
    机器学习入门11
    机器学习入门10
    机器学习入门09
  • 原文地址:https://www.cnblogs.com/oneshot/p/4109524.html
Copyright © 2011-2022 走看看