zoukankan      html  css  js  c++  java
  • BZOJ4012 [HNOI2015]开店

    首先这个叫"动态点分治",不过瞎YY也能YY出来【比如我。。。

    就是记录下点分治的过程和每个点的答案信息,于是查询的时候只要沿着分治好的根一路走下去就行了,于是单次查询的外层复杂度是$O(log n)$的

    对于每个点,要记录以从整棵树到它的分治路径和以它为根的子树内权值小于v的点到它的距离和(就是关于权值的前缀和)

    于是查询一个点的时候只要二分一下就好了。。。

    总复杂度$O((n + Q) * log^2n)$

    写了一晚上QAQQQ

      1 /**************************************************************
      2     Problem: 4012
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:28756 ms
      7     Memory:107560 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12 #include <vector>
     13  
     14 using namespace std;
     15 typedef long long ll;
     16 const int N = 15e4 + 4;
     17  
     18 inline int read();
     19 inline void print(ll);
     20  
     21 struct edge {
     22     int next, to, v;
     23     edge(int _n = 0, int _t = 0, int _v = 0) : next(_n), to(_t), v(_v) {}
     24 } e[N << 1];
     25  
     26 struct data {
     27     int v;
     28     ll dis;
     29     data(int _v = 0, ll _d = 0) : v(_v), dis(_d) {}
     30      
     31     inline bool operator < (const data &p) const {
     32         return v == p.v ? dis < p.dis : v < p.v;
     33     }
     34 };
     35  
     36 struct Path {
     37     int p, s;
     38     ll dis;
     39     Path(int _p = 0, ll _d = 0, int _s = 0) : p(_p), dis(_d), s(_s) {}
     40 };
     41  
     42 struct tree_node {
     43     int v, sz, mx, vis;
     44     vector <Path> path;
     45     vector <data> dis[3];
     46 } tr[N];
     47  
     48 int n, m, mod;
     49 int size, root;
     50 int first[N], tot;
     51 int L, R;
     52 ll ans;
     53  
     54 inline void Add_Edges(int x, int y, int z) {
     55     e[++tot] = edge(first[x], y, z), first[x] = tot;
     56     e[++tot] = edge(first[y], x, z), first[y] = tot;
     57 }
     58  
     59 #define y e[x].to
     60 void get_sz(int p, int fa) {
     61     int x;
     62     tr[p].sz = 1;
     63     for (x = first[p]; x; x = e[x].next)
     64         if (!tr[y].vis && y != fa) {
     65             get_sz(y, p);
     66             tr[p].sz += tr[y].sz;
     67         }
     68 }
     69  
     70 void get_rt(int p, int fa) {
     71     int x;
     72     tr[p].sz = 1, tr[p].mx = 0;
     73     for (x = first[p]; x; x = e[x].next)
     74         if (!tr[y].vis && y != fa) {
     75             get_rt(y, p);
     76             tr[p].sz += tr[y].sz;
     77             tr[p].mx = max(tr[p].mx, tr[y].sz);
     78         }
     79     tr[p].mx = max(tr[p].mx, size - tr[p].sz);
     80     if (tr[p].mx < tr[root].mx) root = p;
     81 }
     82  
     83 void calc(int p, int fa, int tar, int d, int now) {
     84     int x;
     85     tr[p].path.push_back(Path(tar, d, now));
     86     tr[tar].dis[now].push_back(data(tr[p].v, d));
     87     for (x = first[p]; x; x = e[x].next)
     88         if (!tr[y].vis && y != fa)
     89             calc(y, p, tar, d + e[x].v, now);
     90 }
     91  
     92 void work(int p) {
     93     int x, now = 0;
     94     tr[p].vis = 1;
     95     get_sz(p, 0);
     96     tr[p].path.push_back(Path(p, 0, 3));
     97     for (x = first[p]; x; x = e[x].next)
     98         if (!tr[y].vis) calc(y, p, p, e[x].v, now++);
     99     for (x = first[p]; x; x = e[x].next)
    100         if (!tr[y].vis) {
    101             root = 0, size = tr[y].sz;
    102             get_rt(y, 0);
    103             work(root);
    104         }
    105 }
    106 #undef y
    107  
    108 inline ll query(vector <data> *v, ll d, int s) {
    109     static ll res;
    110     static int i, t;
    111     for (i = res = 0; i < 3; ++i) if (i != s) {
    112             t = lower_bound(v[i].begin(), v[i].end(), data(L, -1)) - v[i].begin();
    113             if (t) res -= d * t + v[i][t - 1].dis;
    114             t = lower_bound(v[i].begin(), v[i].end(), data(R + 1, -1)) - v[i].begin();
    115             if (t) res += d * t + v[i][t - 1].dis;
    116         }
    117     return res;
    118 }
    119  
    120 int main() {
    121     int i, j, k, x, y, z, Q, p;
    122     n = read(), Q = read(), mod = read();
    123     for (i = 1; i <= n; ++i) tr[i].v = read();
    124     for (i = 1; i < n; ++i) {
    125         x = read(), y = read(), z = read();
    126         Add_Edges(x, y, z);
    127     }
    128     tr[root = 0].mx = size = n;
    129     get_rt(1, 0);
    130     work(root);
    131     for (i = 1; i <= n; ++i)
    132         for (j = 0; j < 3; ++j) {
    133             sort(tr[i].dis[j].begin(), tr[i].dis[j].end());
    134             for (k = 1; k < tr[i].dis[j].size(); ++k)
    135                 tr[i].dis[j][k].dis += tr[i].dis[j][k - 1].dis;
    136         }
    137     for (ans = 0; Q; --Q) {
    138         p = read(), L = (ans + read()) % mod, R = (ans + read()) % mod;
    139         if (L > R) swap(L, R);
    140         for (i = ans = 0; i < tr[p].path.size(); ++i) {
    141             if (L <= tr[tr[p].path[i].p].v && tr[tr[p].path[i].p].v <= R)
    142                 ans += tr[p].path[i].dis;
    143             ans += query(tr[tr[p].path[i].p].dis, tr[p].path[i].dis, tr[p].path[i].s);
    144         }
    145         print(ans);
    146     }
    147     return 0;
    148 }
    149  
    150 inline int read() {
    151     static int x;
    152     static char ch;
    153     x = 0, ch = getchar();
    154     while (ch < '0' || '9' < ch)
    155         ch = getchar();
    156     while ('0' <= ch && ch <= '9') {
    157         x = x * 10 + ch - '0';
    158         ch = getchar();
    159     }
    160     return x;
    161 }
    162  
    163 inline void print(ll t) {
    164     static int tot, pr[20];
    165     tot = 0;
    166     while (t)
    167         pr[++tot] = t % 10, t /= 10;
    168     if (!tot) putchar('0');
    169     while (tot) putchar(pr[tot--] + '0');
    170     putchar('
    ');
    171 }
    View Code

     (p.s. bz上AC700T纪念!)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    软退回和硬退回的区别和联系
    十家国内知名的EDM服务提供商
    2018年第一记:EDM策略分享-EDM营销的策略分析
    分享几个目前研究出来的邮件不进垃圾箱技巧
    如何快速增加邮件列表用户数量
    EDM数据营销之电商篇| 六大事务性邮件,环环相扣打造极致用户体验!
    如何整合线上和线下营销进行深度交融
    品牌logo在EDM数据营销中的运用
    2017年内容营销如何提高ROI转化率
    营销必读:2017移动应用的五大营销趋势
  • 原文地址:https://www.cnblogs.com/rausen/p/4467631.html
Copyright © 2011-2022 走看看