zoukankan      html  css  js  c++  java
  • 洛谷P4719 动态dp

    动态DP其实挺简单一个东西。

    把DP值的定义改成去掉重儿子之后的DP值。

    重链上的答案就用线段树/lct维护,维护子段/矩阵都可以。其实本质上差不多...

    修改的时候在log个线段树上修改。轻儿子所在重链的线段树的根拿去更新父亲的DP值。

      1 #include <cstdio>
      2 #include <algorithm>
      3 
      4 const int N = 100010, INF = 0x3f3f3f3f;
      5 
      6 template <class T> inline void read(T &x) {
      7     x = 0;
      8     char c = getchar();
      9     bool f = 0;
     10     while(c < '0' || c > '9') {
     11         if(c == '-') {
     12             f = 1;
     13         }
     14         c = getchar();
     15     }
     16     while(c >= '0' && c <= '9') {
     17         x = (x << 3) + (x << 1) + c - 48;
     18         c = getchar();
     19     }
     20     if(f) {
     21         x = (~x) + 1;
     22     }
     23     return;
     24 }
     25 
     26 struct Edge {
     27     int nex, v;
     28 }edge[N << 1]; int tp;
     29 
     30 // 0  0 0
     31 // 1  0 1
     32 // 2  1 0
     33 // 3  1 1
     34 
     35 int top[N], e[N], siz[N], pos[N], id[N], val[N], fa[N], son[N], d[N], num, n, len[N];
     36 int f[N][2], seg[N * 4][4], tot, ls[N * 4], rs[N * 4], rt[N];
     37 
     38 inline void add(int x, int y) {
     39     tp++;
     40     edge[tp].v = y;
     41     edge[tp].nex = e[x];
     42     e[x] = tp;
     43     return;
     44 }
     45 
     46 void DFS_1(int x, int f) { // son siz fa d
     47     fa[x] = f;
     48     d[x] = d[f] + 1;
     49     siz[x] = 1;
     50     for(int i = e[x]; i; i = edge[i].nex) {
     51         int y = edge[i].v;
     52         if(y == f) {
     53             continue;
     54         }
     55         DFS_1(y, x);
     56         siz[x] += siz[y];
     57         if(siz[y] > siz[son[x]]) {
     58             son[x] = y;
     59         }
     60     }
     61     return;
     62 }
     63 
     64 void DFS_2(int x, int f) { // pos id top
     65     top[x] = f;
     66     pos[x] = ++num;
     67     id[num] = x;
     68     len[x] = 1;
     69     if(son[x]) {
     70         DFS_2(son[x], f);
     71         len[x] = len[son[x]] + 1;
     72     }
     73     for(int i = e[x]; i; i = edge[i].nex) {
     74         int y = edge[i].v;
     75         if(y == son[x] || y == fa[x]) {
     76             continue;
     77         }
     78         DFS_2(y, y);
     79     }
     80     return;
     81 }
     82 
     83 inline void pushup(int o) {
     84     int l = ls[o], r = rs[o];
     85     seg[o][0] = std::max(seg[l][0] + seg[r][0], seg[l][0] + seg[r][2]);
     86     seg[o][0] = std::max(seg[o][0], seg[l][1] + seg[r][0]);
     87 
     88     seg[o][1] = std::max(seg[l][0] + seg[r][1], seg[l][0] + seg[r][3]);
     89     seg[o][1] = std::max(seg[o][1], seg[l][1] + seg[r][1]);
     90 
     91     seg[o][2] = std::max(seg[l][2] + seg[r][0], seg[l][2] + seg[r][2]);
     92     seg[o][2] = std::max(seg[o][2], seg[l][3] + seg[r][0]);
     93 
     94     seg[o][3] = std::max(seg[l][2] + seg[r][1], seg[l][2] + seg[r][3]);
     95     seg[o][3] = std::max(seg[o][3], seg[l][3] + seg[r][1]);
     96     return;
     97 }
     98 
     99 inline void build(int l, int r, int &o) {
    100     if(!o) {
    101         o = ++tot;
    102     }
    103     if(l == r) {
    104         seg[o][0] = f[id[r]][0];
    105         seg[o][1] = -INF;
    106         seg[o][2] = -INF;
    107         seg[o][3] = val[id[r]] + f[id[r]][1];
    108         return;
    109     }
    110     int mid = (l + r) >> 1;
    111     build(l, mid, ls[o]);
    112     build(mid + 1, r, rs[o]);
    113     pushup(o);
    114     return;
    115 }
    116 
    117 void change(int p, int l, int r, int o) {
    118     //printf("change -- : %d %d %d 
    ", p, l, r);
    119     if(l == r) {
    120         seg[o][0] = f[id[r]][0];
    121         seg[o][1] = -INF;
    122         seg[o][2] = -INF;
    123         seg[o][3] = val[id[r]] + f[id[r]][1];
    124         //printf("%d = %d + %d 
    ", id[r], val[id[r]], f[id[r]][1]);
    125         return;
    126     }
    127     int mid = (l + r) >> 1;
    128     if(p <= mid) {
    129         change(p, l, mid, ls[o]);
    130     }
    131     else {
    132         change(p, mid + 1, r, rs[o]);
    133     }
    134     pushup(o);
    135     //printf("%d %d 
    ", id[l], id[r]);
    136     //printf("%d %d %d %d 
    ", seg[o][0], seg[o][1], seg[o][2], seg[o][3]);
    137     return;
    138 }
    139 
    140 inline void change(int x, int v) {
    141     //printf("change %d %d 
    ", x, v);
    142     val[x] = v;
    143     while(x) {
    144         int xx = top[x];
    145         if(fa[xx]) {
    146             int temp = std::max(seg[rt[xx]][0], seg[rt[xx]][1]);
    147             f[fa[xx]][1] -= temp;
    148             f[fa[xx]][0] -= std::max(std::max(seg[rt[xx]][2], seg[rt[xx]][3]), temp);
    149         }
    150         //printf("ch %d %d %d 
    ", x, xx, id[pos[xx] + len[xx] - 1]);
    151         change(pos[x], pos[xx], pos[xx] + len[xx] - 1, rt[xx]);
    152         if(fa[xx]) {
    153             int temp = std::max(seg[rt[xx]][0], seg[rt[xx]][1]);
    154             f[fa[xx]][1] += temp;
    155             f[fa[xx]][0] += std::max(std::max(seg[rt[xx]][2], seg[rt[xx]][3]), temp);
    156         }
    157         x = fa[xx];
    158     }
    159     return;
    160 }
    161 
    162 int main() {
    163     int m;
    164     read(n); read(m);
    165     for(int i = 1; i <= n; i++) {
    166         read(val[i]);
    167     }
    168     for(int i = 1, x, y; i < n; i++) {
    169         read(x); read(y);
    170         add(x, y);
    171         add(y, x);
    172     }
    173     DFS_1(1, 0);
    174     DFS_2(1, 1);
    175     for(int i = 1; i <= n; i++) {
    176         int x = id[n + 1 - i];
    177         if(top[x] == x) {
    178             build(pos[x], pos[x] + len[x] - 1, rt[x]);
    179             if(fa[x]) {
    180                 int temp = std::max(seg[rt[x]][0], seg[rt[x]][1]);
    181                 f[fa[x]][1] += temp;
    182                 f[fa[x]][0] += std::max(std::max(seg[rt[x]][2], seg[rt[x]][3]), temp);
    183             }
    184         }
    185     }
    186 
    187     for(int i = 1, x, y; i <= m; i++) {
    188         read(x); read(y);
    189         change(x, y);
    190         int a = std::max(seg[rt[1]][0], seg[rt[1]][1]);
    191         int b = std::max(seg[rt[1]][2], seg[rt[1]][3]);
    192         printf("%d
    ", std::max(a, b));
    193     }
    194 
    195     return 0;
    196 }
    AC代码

    还有noip最后一题,虽然正解是倍增DP但是显然写动态DP啊...

    注意树剖和线段树别写错了..没开O2少用std的函数

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <cmath>
      5 
      6 typedef long long LL;
      7 const int N = 100010;
      8 const LL INF = 1e17;
      9 
     10 template <class T> inline void read(T &x) {
     11     x = 0;
     12     char c = getchar();
     13     while(c < '0' || c > '9') {
     14         c = getchar();
     15     }
     16     while(c >= '0' && c <= '9') {
     17         x = (x << 3) + (x << 1) + c - 48;
     18         c = getchar();
     19     }
     20     return;
     21 }
     22 
     23 struct Edge {
     24     int nex, v;
     25 }edge[N * 2]; int tp;
     26 
     27 LL val[N], f[N * 4][2][2], Val[N][2];
     28 int e[N], n, m;
     29 int fa[N], top[N], pos[N], id[N], siz[N], son[N], num, d[N], ed[N]; // tree div
     30 int tot, ls[N * 4], rs[N * 4], rt[N]; // segment tree
     31 char str[3];
     32 
     33 inline void add(int x, int y) {
     34     tp++;
     35     edge[tp].v = y;
     36     edge[tp].nex = e[x];
     37     e[x] = tp;
     38     return;
     39 }
     40 
     41 void DFS_1(int x, int f) { // fa son siz d
     42     fa[x] = f;
     43     siz[x] = 1;
     44     d[x] = d[f] + 1;
     45     for(int i = e[x]; i; i = edge[i].nex) {
     46         int y = edge[i].v;
     47         if(y == f) {
     48             continue;
     49         }
     50         DFS_1(y, x);
     51         siz[x] += siz[y];
     52         if(siz[y] > siz[son[x]]) {
     53             son[x] = y;
     54         }
     55     }
     56     //printf("son %d = %d 
    ", x, son[x]);
     57     //printf("siz %d = %d 
    ", x, siz[x]);
     58     return;
     59 }
     60 
     61 void DFS_2(int x, int f) { // top pos id
     62     pos[x] = ++num;
     63     top[x] = f;
     64     id[num] = x;
     65     ed[f] = num;
     66     //printf("x = %d ed %d = %d 
    ", x, f, ed[f]);
     67     if(son[x]) {
     68         DFS_2(son[x], f);
     69     }
     70     for(int i = e[x]; i; i = edge[i].nex) {
     71         int y = edge[i].v;
     72         if(y == fa[x] || y == son[x]) {
     73             continue;
     74         }
     75         DFS_2(y, y);
     76     }
     77     return;
     78 }
     79 
     80 inline LL mymin(LL x, LL y) {
     81     return x < y ? x : y;
     82 }
     83 
     84 inline void exmin(LL &a, LL b) {
     85     a > b ? a = b : 0;
     86     return;
     87 }
     88 
     89 inline void pushup(int o) {
     90     int l = ls[o], r = rs[o];
     91     f[o][0][0] = INF;
     92     exmin(f[o][0][0], f[l][0][1] + f[r][0][0]);
     93     exmin(f[o][0][0], f[l][0][1] + f[r][1][0]);
     94     exmin(f[o][0][0], f[l][0][0] + f[r][1][0]);
     95     f[o][0][1] = INF;
     96     exmin(f[o][0][1], f[l][0][1] + f[r][0][1]);
     97     exmin(f[o][0][1], f[l][0][1] + f[r][1][1]);
     98     exmin(f[o][0][1], f[l][0][0] + f[r][1][1]);
     99     f[o][1][0] = INF;
    100     exmin(f[o][1][0], f[l][1][1] + f[r][0][0]);
    101     exmin(f[o][1][0], f[l][1][1] + f[r][1][0]);
    102     exmin(f[o][1][0], f[l][1][0] + f[r][1][0]);
    103     f[o][1][1] = INF;
    104     exmin(f[o][1][1], f[l][1][1] + f[r][0][1]);
    105     exmin(f[o][1][1], f[l][1][1] + f[r][1][1]);
    106     exmin(f[o][1][1], f[l][1][0] + f[r][1][1]);
    107     return;
    108 }
    109 
    110 void build(int l, int r, int &o) {
    111     if(!o) {
    112         o = ++tot;
    113     }
    114     if(l == r) {
    115         // init
    116         int x = id[r];
    117         f[o][0][0] = Val[x][0];
    118         f[o][0][1] = INF;
    119         f[o][1][0] = INF;
    120         f[o][1][1] = val[x] + Val[x][1];
    121         return;
    122     }
    123     int mid = (l + r) >> 1;
    124     build(l, mid, ls[o]);
    125     build(mid + 1, r, rs[o]);
    126     pushup(o);
    127     return;
    128 }
    129 
    130 inline int lca(int x, int y) {
    131     while(top[x] != top[y]) {
    132         if(d[top[x]] <= d[top[y]]) {
    133             y = fa[top[y]];
    134         }
    135         else {
    136             x = fa[top[x]];
    137         }
    138     }
    139     return (d[x] < d[y]) ? x : y;
    140 }
    141 
    142 inline bool link(int x, int y) {
    143     int z = lca(x, y);
    144     return std::abs(d[x] - d[y]) == 1 && (z == x || z == y);
    145 }
    146 
    147 inline void change(int p, int v, int l, int r, int o) {
    148     //printf("change %d %d %d %d 
    ", p, v, l, r);
    149     if(l == r) {
    150         if(v) {
    151             f[o][0][0] = INF;
    152         }
    153         else {
    154             f[o][1][1] = INF;
    155         }
    156         return;
    157     }
    158     int mid = (l + r) >> 1;
    159     if(p <= mid) {
    160         change(p, v, l, mid, ls[o]);
    161     }
    162     else {
    163         change(p, v, mid + 1, r, rs[o]);
    164     }
    165     pushup(o);
    166     return;
    167 }
    168 
    169 inline void update(int p, int l, int r, int o) {
    170     if(l == r) {
    171         int x = id[r];
    172         f[o][0][0] = Val[x][0];
    173         f[o][1][1] = val[x] + Val[x][1];
    174         return;
    175     }
    176     int mid = (l + r) >> 1;
    177     if(p <= mid) {
    178         update(p, l, mid, ls[o]);
    179     }
    180     else {
    181         update(p, mid + 1, r, rs[o]);
    182     }
    183     pushup(o);
    184     return;
    185 }
    186 
    187 inline void change(int x, int a) {
    188     int xx = x;
    189     while(x) {
    190         if(fa[top[x]]) {
    191             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
    192             Val[fa[top[x]]][0] -= temp;
    193             Val[fa[top[x]]][1] -= mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
    194         }
    195         if(x != xx)
    196             update(pos[x], pos[top[x]], ed[top[x]], rt[top[x]]);
    197         else
    198             change(pos[x], a, pos[top[x]], ed[top[x]], rt[top[x]]);
    199         if(fa[top[x]]) {
    200             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
    201             Val[fa[top[x]]][0] += temp;
    202             Val[fa[top[x]]][1] += mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
    203         }
    204         x = fa[top[x]];
    205     }
    206     return;
    207 }
    208 
    209 inline void recover(int x) {
    210     while(x) {
    211         if(fa[top[x]]) {
    212             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
    213             Val[fa[top[x]]][0] -= temp;
    214             Val[fa[top[x]]][1] -= mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
    215         }
    216         update(pos[x], pos[top[x]], ed[top[x]], rt[top[x]]);
    217         if(fa[top[x]]) {
    218             LL temp = mymin(f[rt[top[x]]][1][0], f[rt[top[x]]][1][1]);
    219             Val[fa[top[x]]][0] += temp;
    220             Val[fa[top[x]]][1] += mymin(mymin(f[rt[top[x]]][0][0], f[rt[top[x]]][0][1]), temp);
    221         }
    222         x = fa[top[x]];
    223     }
    224     return;
    225 }
    226 
    227 int main() {
    228 
    229     //freopen("in.in", "r", stdin);
    230     //freopen("my.out", "w", stdout);
    231     read(n); read(m);
    232     scanf("%s", str);
    233     for(register int i = 1; i <= n; i++) {
    234         read(val[i]);
    235     }
    236     for(register int i = 1, x, y; i < n; i++) {
    237         read(x); read(y);
    238         add(x, y); add(y, x);
    239     }
    240     // prework
    241     DFS_1(1, 0);
    242     DFS_2(1, 1);
    243     // build
    244     for(register int a = n; a >= 1; a--) {
    245         int x = id[a];
    246         if(top[x] == x) {
    247             build(pos[x], ed[x], rt[x]);
    248             if(fa[x]) {
    249                 int father = fa[x];
    250                 LL temp = mymin(f[rt[x]][1][0], f[rt[x]][1][1]);
    251                 Val[father][0] += temp;
    252                 Val[father][1] += mymin(mymin(f[rt[x]][0][0], f[rt[x]][0][1]), temp);
    253             }
    254         }
    255     }
    256 
    257     for(register int i = 1, x, a, y, b; i <= m; i++) {
    258         scanf("%d%d%d%d", &x, &a, &y, &b);
    259         if(!a && !b && link(x, y)) {
    260             puts("-1");
    261             continue;
    262         }
    263         change(x, a);
    264         change(y, b);
    265         printf("%lld
    ", mymin(mymin(f[rt[1]][0][0], f[rt[1]][1][1]), mymin(f[rt[1]][0][1], f[rt[1]][1][0])));
    266         recover(x);
    267         recover(y);
    268     }
    269 
    270     return 0;
    271 }
    AC代码
  • 相关阅读:
    xutils 上传文件 ,暂时
    UIView.FRAMEWORK
    2016.11.7
    2016.11.6新阶段开始
    远程推送
    xcode8 导入 dylib
    bugly使用
    anelife
    心阶段
    新阶段
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10389209.html
Copyright © 2011-2022 走看看