zoukankan      html  css  js  c++  java
  • BZOJ4381 : [POI2015]Odwiedziny / Luogu3591[POI2015]ODW

    Solution

    在步伐$pace$比较小的时候, 我们发现用前缀和直接维护会很快

    而在$pace$比较大的时候, 则暴力往上跳会最优

    设$blo= sqrt{N}$

    若$pace<=blo$, 则利用前缀和更新, 

    预处理复杂度$O(N sqrt{N})$, 查询复杂度$O(1)$

    若$pace>blo$,则利用树剖逐渐往上跳

    总共要跳$N/pace$次, 一共有$logN$条轻重链, 复杂度为$O(logN+ sqrt{N})$

    代码实现比较麻烦, 我常数写的还很差, 水平低啊QAQ

    Code

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cmath>
      5 #define rd read()
      6 #define N 50005
      7 #define M 240
      8 #define R register
      9 using namespace std;
     10 
     11 int n, blo, a[N], b[N], f[N][M], sum[N][M];
     12 int fa[N], dep[N], top[N], sz[N], son[N], id[N], idf[N], cnt;
     13 int head[N], tot;
     14 
     15 struct edge {
     16     int nxt, to;
     17 }e[N << 1];
     18 
     19 inline char nc(){
     20     static char buf[100000], *p1=buf, *p2=buf;
     21     return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
     22 }
     23 inline int read(){
     24     char ch = nc();int sum = 0;
     25     while(!(ch >= '0' && ch <= '9')) ch = nc();
     26     while(ch >= '0' && ch <= '9') sum = sum * 10 + ch - 48, ch = nc();
     27     return sum;
     28 }
     29 
     30 inline void add(int u, int v) {
     31     e[++tot].to = v;
     32     e[tot].nxt = head[u];
     33     head[u] = tot;
     34 }
     35 
     36 inline void sw(int &A, int &B) {
     37     A ^= B; B ^= A; A ^= B;
     38 }
     39 
     40 inline void dfs1(R int u) {
     41     sz[u] = 1;
     42     for (R int i = head[u]; i; i = e[i].nxt) {
     43         R int nt = e[i].to;
     44         if (nt == fa[u]) continue;
     45         f[nt][1] = fa[nt] = u;
     46         dep[nt] = dep[u] + 1;
     47         dfs1(nt);
     48         sz[u] += sz[nt];
     49         if (sz[nt] > sz[son[u]])
     50             son[u] = nt;
     51     }
     52 }
     53 
     54 inline void dfs2(R int u) {
     55     idf[id[u] = ++cnt] = u;
     56     if (!son[u]) return;
     57     top[son[u]] = top[u];
     58     dfs2(son[u]);
     59     for (R int i = head[u]; i; i = e[i].nxt) {
     60         R int nt = e[i].to;
     61         if (nt == fa[u] || nt == son[u]) continue;
     62         top[nt] = nt;
     63         dfs2(nt);
     64     }
     65 }
     66 
     67 inline int LCA(R int x, R int y) {
     68     for (;top[x] != top[y]; ) {
     69         if (dep[top[x]] < dep[top[y]]) sw(x, y);
     70         x = fa[top[x]];
     71     }
     72     if (dep[x] < dep[y]) sw(x, y);
     73     return y;
     74 }
     75 
     76 inline int work1(R int x, R int y, R int pace) {
     77     R int lca = LCA(x, y), len = dep[x] + dep[y] - 2 * dep[lca], res = 0;
     78     if (len % pace) {
     79         res += a[y];
     80         y = f[y][len % pace];
     81         len -= len % pace;
     82     }
     83     len = dep[x] - dep[lca];
     84     if (len % pace == 0) {
     85         res += sum[x][pace] - sum[lca][pace];
     86         res += sum[y][pace] - sum[lca][pace];
     87         res += a[lca];
     88         return res;
     89     }
     90     R int tmp = f[lca][pace - len % pace];
     91     res += sum[x][pace] - sum[tmp][pace];
     92     if (dep[y] < dep[lca]) return res;
     93     len = dep[y] - dep[lca];
     94     tmp = f[lca][pace - len % pace];
     95     res += sum[y][pace] - sum[tmp][pace];
     96     return res;
     97 }
     98 
     99 inline int up(R int x, R int d) {
    100     R int y = top[x];
    101     for (; x && dep[x] - dep[y] < d;) {
    102         d -= dep[x] - dep[y] + 1;
    103         x = fa[top[x]];
    104         y = top[x];
    105     }
    106     if (!x) return 0;
    107     return idf[id[x] - d];
    108 }
    109 
    110 inline int work2(R int x, R int y, R int pace) {
    111     R int lca = LCA(x, y), len = dep[x] + dep[y] - 2 * dep[lca], res = 0;
    112     if (len % pace) {
    113         res += a[y];
    114         y = up(y, len % pace);
    115         len -= len % pace;
    116     }
    117     len = dep[x] - dep[lca];
    118     if (len % pace == 0) {
    119         while (x && dep[x] > dep[lca])
    120             res += a[x], x = up(x, pace);
    121         while (y && dep[y] > dep[lca])
    122             res += a[y], y = up(y, pace);
    123         res += a[lca];
    124         return res;
    125     }
    126     while (x && dep[x] > dep[lca])
    127         res += a[x], x = up(x, pace);
    128     while (y && dep[y] > dep[lca])
    129         res += a[y], y = up(y, pace);
    130     return res;
    131 }
    132 
    133 int main()
    134 {
    135     n = rd; blo = sqrt(n);
    136     for (R int i = 1; i <= n; ++i)
    137         a[i] = rd;
    138     for (R int i = 1; i < n; ++i) {
    139         int u = rd, v = rd;
    140         add(u, v); add(v, u);
    141     }
    142     dep[1] = 1; dfs1(1);
    143     top[1] = 1; dfs2(1);
    144     for (R int j = 2; j <= blo; ++j)
    145         for (R int i = 1; i <= n; ++i)
    146             f[i][j] = f[f[i][j - 1]][1];
    147     for (R int j = 1; j <= blo; ++j)
    148         for (R int i = 1; i <= n; ++i) 
    149             sum[i][j] = a[i];
    150     for (R int j = 1; j <= blo; ++j)
    151         for (R int i = 1; i <= n; ++i) {
    152             int x = idf[i];
    153             sum[x][j] += sum[f[x][j]][j];
    154         }
    155     for (R int i = 1; i <= n; ++i) b[i] = rd;
    156     for (R int i = 1; i < n; ++i) {
    157         R int x = rd;
    158         if (x <= blo) printf("%d
    ", work1(b[i], b[i + 1], x));
    159         else printf("%d
    ", work2(b[i], b[i + 1], x));
    160     }
    161 }
    View Code
  • 相关阅读:
    产生渐变色的view
    新建一个去除storyboard的项目
    绘制波形图
    文件系统扫描的工具类
    如何动态绘制时钟
    Xcode插件管理器Alcatraz的使用
    UITableView的headerView展开缩放动画
    POPSpring动画参数详解
    Java枚举类使用和总结
    Java判断不为空的工具类总结
  • 原文地址:https://www.cnblogs.com/cychester/p/9846172.html
Copyright © 2011-2022 走看看