zoukankan      html  css  js  c++  java
  • BZOJ3697 采药人的路径

    点分治。。。尼玛啊!蒟蒻怎么做的那么桑心%>_<%

    Orz hzwer

    蒟蒻就补充一下hzwer没讲的东西:

    (1)对于阴性的植物权值设为-1,阳性的设为+1

    (2)最后一段就是讲如何利用新的子树的f[]值求出ans和更新g[]

      1 /**************************************************************
      2     Problem: 3697
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:1752 ms
      7     Memory:15924 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 using namespace std;
     14 const int N = 100005;
     15  
     16 struct edge {
     17     int next, to, v;
     18     edge() {}
     19     edge(int _n, int _t, int _v) : next(_n), to(_t), v(_v) {}
     20 } e[N << 1];
     21   
     22 int first[N], tot;
     23   
     24 struct tree_node {
     25     int sz, dep, dis;
     26     bool vis;
     27 } tr[N];
     28   
     29 int n, k;
     30 int cnt[N << 1];
     31 long long f[N << 1][2], g[N << 1][2], ans;
     32 int Root, Maxsz;
     33 int mx_dep, mx;
     34  
     35 inline int read() {
     36     int x = 0;
     37     char ch = getchar();
     38     while (ch < '0' || '9' < ch)
     39         ch = getchar();
     40     while ('0' <= ch && ch <= '9') {
     41         x = x * 10 + ch - '0';
     42         ch = getchar();
     43     }
     44     return x;
     45 }
     46  
     47 void Add_Edges(int x, int y, int z) {
     48     e[++tot] = edge(first[x], y, z), first[x] = tot;
     49     e[++tot] = edge(first[y], x, z), first[y] = tot;
     50 }
     51   
     52 void dfs(int p, int fa, int sz) {
     53     int x, y, maxsz = 0;
     54     tr[p].sz = 1;
     55     for (x = first[p]; x; x = e[x].next)
     56         if ((y = e[x].to) != fa && !tr[y].vis) {
     57             dfs(y, p, sz);
     58             tr[p].sz += tr[y].sz;
     59             maxsz = max(maxsz, tr[y].sz);
     60         }
     61     maxsz = max(maxsz, sz - tr[p].sz);
     62     if (maxsz < Maxsz)
     63         Root = p, Maxsz = maxsz;
     64 }
     65   
     66 int get_root(int p, int sz) {
     67     Maxsz = N << 1;
     68     dfs(p, 0, sz);
     69     return Root;
     70 }
     71  
     72 void Dfs(int p, int fa) {
     73     int x, y;
     74     mx_dep = max(mx_dep, tr[p].dep);
     75     if (cnt[tr[p].dis]) ++f[tr[p].dis][1];
     76     else ++f[tr[p].dis][0];
     77     ++cnt[tr[p].dis];
     78     for (x = first[p]; x; x = e[x].next)
     79         if ((y = e[x].to) != fa && !tr[y].vis) {
     80             tr[y].dep = tr[p].dep + 1, tr[y].dis = tr[p].dis + e[x].v;
     81             Dfs(y, p);
     82         }
     83     --cnt[tr[p].dis];
     84 }
     85  
     86 void cal(int p) {
     87     int x, y, j;
     88     mx = 0, g[n][0] = 1;
     89     for (x = first[p]; x; x = e[x].next)
     90         if (!tr[y = e[x].to].vis) {
     91             tr[y].dis = n + e[x].v, tr[y].dep = 1, mx_dep = 1;
     92             Dfs(y, p);
     93             mx = max(mx, mx_dep);
     94             ans += (g[n][0] - 1) * f[n][0];
     95             for (j = -mx_dep; j <= mx_dep; ++j)
     96                 ans += g[n - j][1] * f[n + j][1] + g[n - j][0] * f[n + j][1] + g[n - j][1] * f[n + j][0];           
     97             for (j = n - mx_dep; j <= n + mx_dep; ++j) {
     98                 g[j][0] += f[j][0], g[j][1] += f[j][1];
     99                 f[j][0] = f[j][1] = 0;
    100             }
    101         }
    102     for (j = n - mx; j <= n + mx; ++j)
    103         g[j][0] = g[j][1] = 0;
    104 }
    105  
    106 void work(int p, int sz) {
    107     int root = get_root(p, sz), x, y;
    108     tr[root].vis = 1;
    109     cal(root);
    110     for (x = first[root]; x; x = e[x].next)
    111         if (!tr[y = e[x].to].vis)
    112             work(y, tr[y].sz);
    113 }
    114  
    115 int main() {
    116     int i, x, y, z;
    117     n = read();
    118     for (i = 1; i < n; ++i) {
    119         x = read(), y = read(), z = read();
    120         Add_Edges(x, y, z ? 1 : -1);
    121     }
    122     work(1, n);
    123     printf("%lld
    ", ans);
    124     return 0;
    125 }
    View Code

     (p.s.  其实我觉得吧。。。点分治做到1600ms是极限了,rank最前面的两位应该用了特殊的技♂巧

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    HTTP解决了什么问题?
    OSI模型--TCP/IP
    USB取证工具-Usbrip
    ModSecurity OWASP 规则集说明
    WAF简介及ModSecurity-nginx搭建
    aSYNcrone-ddos
    Centos7安装php7.1
    Centos7基于LNMP架构搭建DVWA
    web扫描器-uniscan
    基于腾讯云搭建宝塔面板
  • 原文地址:https://www.cnblogs.com/rausen/p/4175940.html
Copyright © 2011-2022 走看看