zoukankan      html  css  js  c++  java
  • HDU5044---Tree 树链剖分

    大致题意:add1 u v   u到v路径上所有点的权值加上k,add2  u 到v路径上所有边的权值加上k

    最后输出所有点的权值,边的权值。。树链剖分预处理然后来个线性O(n)的操作。刚开始用线段树tle了.

      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <algorithm>
      7 using namespace std;
      8 typedef unsigned long long ull;
      9 typedef long long ll;
     10 const int inf = 0x3f3f3f3f;
     11 const int maxn = 1e5+10;
     12 struct
     13 {
     14     int  to,next;
     15 } e[maxn<<1];
     16 int head[maxn],edge;
     17 void add(int x,int y)
     18 {
     19     e[edge].to = y;
     20     e[edge].next = head[x];
     21     head[x] = edge++;
     22 }
     23 
     24 int son[maxn],fa[maxn],siz[maxn],dep[maxn];
     25 void dfs1(int root)
     26 {
     27     siz[root] = 1;
     28     son[root] = 0;
     29     for (int i = head[root]; i > 0; i = e[i].next)
     30     {
     31         if (fa[root] != e[i].to)
     32         {
     33             dep[e[i].to] = dep[root] + 1;
     34             fa[e[i].to] = root;
     35             dfs1(e[i].to);
     36             if (siz[son[root]] < siz[e[i].to])
     37                 son[root] = e[i].to;
     38             siz[root] += siz[e[i].to];
     39         }
     40     }
     41 }
     42 int top[maxn],pos[maxn],fp[maxn],tot;
     43 void dfs2(int root,int f)
     44 {
     45     top[root] = f;
     46     pos[root] = tot++;
     47     fp[pos[root]] = root;
     48     if (son[root]>0)
     49         dfs2(son[root],top[root]);
     50     for (int i = head[root]; i > 0; i = e[i].next)
     51         if (fa[root] != e[i].to && e[i].to != son[root])
     52             dfs2(e[i].to,e[i].to);
     53 }
     54 ll addv[3][maxn<<2];
     55 int k;
     56 void pre_update(int ua,int ub,int cho)
     57 {
     58     int f1 = top[ua];
     59     int f2 = top[ub];
     60     while (f1 != f2)
     61     {
     62         if (dep[f1] < dep[f2])
     63             swap(f1,f2),swap(ua,ub);
     64         addv[cho][pos[f1]] += k;
     65         addv[cho][pos[ua]+1] -= k;
     66         ua = fa[f1];
     67         f1 = top[ua];
     68     }
     69     if (dep[ua] > dep[ub])
     70         swap(ua,ub);
     71     if (cho == 1)
     72         addv[cho][pos[ua]] += k,addv[cho][pos[ub]+1] -= k;
     73     if (cho == 2)
     74         addv[cho][pos[son[ua]]] += k,addv[cho][pos[ub]+1] -= k;
     75 }
     76 int n,m,d[maxn][2],link[maxn];
     77 void init()
     78 {
     79     scanf ("%d%d",&n,&m);
     80     int root = 1;
     81     dep[root] = fa[root] = 0;
     82     edge = tot = 1;
     83     memset(head,0,sizeof(head));
     84     memset(siz,0,sizeof(siz));
     85     memset(addv,0,sizeof(addv));
     86     for (int i = 1; i < n; i++)
     87     {
     88         int u,v;
     89         scanf ("%d%d",&u,&v);
     90         d[i][0] = u;
     91         d[i][1] = v;
     92         add(u,v),add(v,u);
     93     }
     94     dfs1(root);
     95     dfs2(root,root);
     96     for (int i = 1; i < n; i++)
     97     {
     98         if (dep[d[i][0]] < dep[d[i][1]])
     99             swap(d[i][0],d[i][1]);
    100         link[d[i][0]] = i;
    101     }
    102 }
    103 ll ans1[maxn],ans2[maxn];
    104 int main(void)
    105 {
    106     //freopen("in.txt","r",stdin);
    107     int t;
    108     int cas = 1;
    109     scanf ("%d",&t);
    110     while (t--)
    111     {
    112         init();
    113         for (int i = 0; i < m; i++)
    114         {
    115             char op[10];
    116             int u,v;
    117             scanf ("%s%d%d%d",op,&u,&v,&k);
    118             pre_update(u,v,op[3]-'0');
    119         }
    120         for (int i = 1; i <= n; i++)
    121         {
    122             addv[1][i] += addv[1][i-1];
    123             addv[2][i] += addv[2][i-1];
    124             ans1[fp[i]] = addv[1][i];
    125             ans2[link[fp[i]]] = addv[2][i];
    126         }
    127         printf("Case #%d:
    ",cas++);
    128         printf("%I64d",ans1[1]);
    129         for (int i = 2; i <= n; i++)
    130         {
    131             printf(" %I64d",ans1[i]);
    132         }
    133         printf("
    ");
    134         if (n>1)
    135             printf("%I64d",ans2[1]);
    136         for (int i = 2; i < n; i++)
    137         {
    138             printf(" %I64d",ans2[i]);
    139         }
    140         printf("
    ");
    141     }
    142     return 0;
    143 }
    View Code
  • 相关阅读:
    多色图标字体
    css编写规则BEM
    css处理工具PostCss
    vue2.0点击其他任何地方隐藏dom
    vue2.0多页面开发
    Dijkstra算法(邻接矩阵存储)
    kmp算法c++代码实现
    最小生成树(prim算法,Kruskal算法)c++实现
    字符串匹配的KMP算法(转)
    筛选法求素数
  • 原文地址:https://www.cnblogs.com/oneshot/p/4017698.html
Copyright © 2011-2022 走看看