zoukankan      html  css  js  c++  java
  • codeforces293E (树上点分治+树状数组)

    和poj1747相比起来,只不过是限制条件多了一维。 

    而多了这一维,所以需要用树状数组来维护,从而快速得到答案。

    因为没注意传进树状数组函数的参数可能是<=0的,导致超时了好久。

      1 #pragma warning(disable:4996)
      2 #pragma comment(linker, "/STACK:1024000000,1024000000")
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <time.h>
      6 #include <math.h>
      7 #include <map>
      8 #include <set>
      9 #include <queue>
     10 #include <stack>
     11 #include <vector>
     12 #include <bitset>
     13 #include <algorithm>
     14 #include <iostream>
     15 #include <string>
     16 #include <functional>
     17 const int INF = 1 << 30;
     18 typedef __int64 LL;
     19 /**/
     20 const int N = 100000 + 10;
     21 
     22 int n, L, W;
     23 struct Edge
     24 {
     25     int to, dis, next;
     26 }g[N*2];
     27 struct Node
     28 {
     29     int l, w;
     30     bool operator<(const Node&rhs)const
     31     {
     32         return w < rhs.w;
     33     }
     34 }a[N];
     35 int head[N], e;
     36 int tree[N];
     37 int size[N], p, total, mins, root;
     38 bool vis[N];
     39 LL ans;
     40 int maxL;
     41 int lowbit(int x)
     42 {
     43     return x &(-x);
     44 }
     45 
     46 //树状数组如果pos<=0,那么会死循环, 卡这里超时了好久。
     47 void modify(int pos, int val)
     48 {
     49     pos += 1;
     50     while (pos <= maxL+1)
     51     {
     52         tree[pos] += val;
     53         pos += lowbit(pos);
     54     }
     55 }
     56 int getSum(int pos)
     57 {
     58     pos += 1;
     59     if (pos <= 0) return 0;
     60     int ret = 0;
     61     while (pos > 0)
     62     {
     63         ret += tree[pos];
     64         pos -= lowbit(pos);
     65     }
     66     return ret;
     67 }
     68 
     69 void addEdge(int u, int v, int dis)
     70 {
     71     g[e].to = v;
     72     g[e].dis = dis;
     73     g[e].next = head[u];
     74     head[u] = e++;
     75 }
     76 
     77 void getRoot(int u, int fa)
     78 {
     79     int maxs = 0;
     80     size[u] = 1;
     81     for (int i = head[u];i != -1;i = g[i].next)
     82     {
     83         int v = g[i].to;
     84         if (v == fa || vis[v]) continue;
     85         getRoot(v, u);
     86         size[u] += size[v];
     87         maxs = std::max(maxs, size[v]);
     88     }
     89     maxs = std::max(maxs, total - size[u]);
     90     if (mins > maxs)
     91     {
     92         mins = maxs;
     93         root = u;
     94     }
     95 }
     96 void getA(int u, int fa, int l, int w)
     97 {
     98     a[p].l = l;
     99     a[p++].w = w;
    100     maxL = std::max(maxL, l);
    101     for (int i = head[u];i != -1;i = g[i].next)
    102     {
    103         int v = g[i].to;
    104         if (v == fa || vis[v]) continue;
    105         getA(v, u, l + 1, w + g[i].dis);
    106     }
    107 }
    108 
    109 LL counts(int u, int ll, int ww)
    110 {
    111     p = 0;
    112     maxL = 0;
    113     getA(u, -1, ll, ww);
    114     std::sort(a, a + p);
    115     int l = 0, r = p - 1;
    116     LL ret = 0;
    117     while (l < r &&a[l].w + a[r].w>W)
    118         r--;
    119     if (l < r)
    120     {
    121         for (int i = l+1;i <= r;++i)
    122             modify(a[i].l,1);
    123         while (l < r)
    124         {
    125             if (a[l].w + a[r].w <= W)
    126             {
    127                 ret += getSum(std::min(L - a[l].l,maxL));
    128                 l++;
    129                 modify(a[l].l,-1);
    130             }
    131             else
    132             {
    133                 modify(a[r].l,-1);
    134                 r--;
    135             }
    136         }
    137     }
    138     return ret;
    139 }
    140 
    141 void go(int u)
    142 {
    143     vis[u] = true;
    144     ans += counts(u, 0, 0);
    145     for (int i = head[u];i != -1;i = g[i].next)
    146     {
    147         int v = g[i].to;
    148         if (vis[v]) continue;
    149         ans -= counts(v, 1, g[i].dis);
    150         mins = INF;
    151         total = size[v];
    152         getRoot(v, -1);
    153         go(root);
    154     }
    155 }
    156 int main()
    157 {
    158     scanf("%d%d%d", &n, &L, &W);
    159     
    160     int u, v, dis;
    161     memset(head, -1, sizeof(head));
    162     for (int i = 1;i < n;++i)
    163     {
    164         u = i + 1;
    165         scanf("%d%d", &v, &dis);
    166         addEdge(u, v, dis);
    167         addEdge(v, u, dis);
    168     }
    169     mins = INF;
    170     total = n;
    171     getRoot(1, -1);
    172     go(root);
    173     printf("%I64d
    ", ans);
    174     
    175     return 0;
    176 }
    View Code
  • 相关阅读:
    Selenium之编辑框操作
    Selenium之勾选框操作
    Selenium之单选框操作
    [复习资料]组合计数学习笔记
    ARC104游记
    [被踩计划] 题解 [省选联考 2020 A 卷] 作业题
    题解 [SEERC2019]Game on a Tree
    [被踩计划] 题解 [NOI2020]美食家
    [被踩计划] 题解 [省选联考 2020 A 卷] 组合数问题
    [被踩计划] 题解 括号树
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4769820.html
Copyright © 2011-2022 走看看