zoukankan      html  css  js  c++  java
  • #2:在颓宅的边缘开始试探——4

    洛谷3372,才开始学segment tree,初级板子。

     1 #include <cstdio>
     2 #define ll long long
     3 #define maxn 100001
     4 
     5 int n, m;
     6 ll a[maxn], sum[maxn << 2], tag[maxn << 2];
     7 
     8 int ls(int p) {
     9     return p << 1;
    10 }
    11 
    12 int rs(int p) {
    13     return p << 1 | 1;
    14 }
    15 
    16 void f(int l, int r, ll k, int p) {
    17     tag[p] += k;
    18     sum[p] += k*(r-l+1);
    19 }
    20 
    21 void push_down(int l, int r, int p) {
    22     int mid = (l + r) >> 1;
    23     f(l, mid, tag[p], ls(p));
    24     f(mid+1, r, tag[p], rs(p));
    25     tag[p] = 0;
    26 }
    27 
    28 void push_up(int p) {
    29     sum[p] = sum[ls(p)] + sum[rs(p)];
    30 }
    31 
    32 void build(int l, int r, int p) {
    33     tag[p] = 0;
    34     if (l == r) {
    35         sum[p] = a[l];
    36         return;
    37     }
    38     int mid = (l + r) >> 1;
    39     build(l, mid, ls(p));
    40     build(mid+1, r, rs(p));
    41     push_up(p);
    42 }
    43 
    44 void update(int nl, int nr, ll k, int l, int r, int p) {
    45     if (nl <= l && r <= nr) {
    46         sum[p] += k*(r-l+1);
    47         tag[p] += k;
    48         return;
    49     }
    50     push_down(l, r, p);
    51     int mid = (l + r) >> 1;
    52     if (nl <= mid)    update(nl, nr, k, l, mid, ls(p));
    53     if (mid < nr)    update(nl, nr, k, mid+1, r, rs(p));
    54     push_up(p);
    55 }
    56 
    57 ll query(int nl, int nr, int l, int r, int p) {
    58     if (nl <= l && r <= nr)    return sum[p];
    59     push_down(l, r, p);
    60     ll ret = 0ll;
    61     int mid = (l + r) >> 1;
    62     if (nl <= mid)    ret += query(nl, nr, l, mid, ls(p));
    63     if (mid < nr)    ret += query(nl, nr, mid+1, r, rs(p));
    64     return ret;
    65 }
    66 
    67 int main() {
    68     scanf("%d%d", &n, &m);
    69     for (int i = 1; i <= n; i++) {
    70         scanf("%lld", &a[i]);
    71     }
    72     build(1, n, 1);
    73     for (int i = 1; i <= m; i++) {
    74         int does, x, y;
    75         scanf("%d%d%d", &does, &x, &y);
    76         if (does == 1) {
    77             ll k;
    78             scanf("%lld", &k);
    79             update(x, y, k, 1, n, 1);
    80         } else {
    81             printf("%lld
    ", query(x, y, 1, n, 1));
    82         }
    83     }
    84     return 0;
    85 }
    View Code

    spojGSS3,要维护区间最大连续子段和,得同时用线段树维护前缀、后缀、和、最大连续和。按照上一个板子写到query时发现要query一大堆……只好改用结构体式的板子。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 #define maxn 50001
     6 #define init(a, b) memset(a, b, sizeof(a))
     7 #define inf 0xcfcfcfcf
     8 
     9 int n, m, a[maxn];
    10 struct T {
    11     int l, r;
    12     int sum, lmax, rmax, maxx;
    13 }t[maxn<<2];
    14 
    15 int ls(int p) {
    16     return p << 1;
    17 }
    18 
    19 int rs(int p) {
    20     return p << 1 | 1;
    21 }
    22 
    23 void push_up(int p) {
    24     t[p].sum = t[ls(p)].sum + t[rs(p)].sum;
    25     t[p].lmax = max(t[ls(p)].lmax, t[ls(p)].sum + t[rs(p)].lmax);
    26     t[p].rmax = max(t[rs(p)].rmax, t[rs(p)].sum + t[ls(p)].rmax);
    27     t[p].maxx = max(max(t[ls(p)].maxx, t[rs(p)].maxx), t[rs(p)].lmax+t[ls(p)].rmax);
    28 }
    29 
    30 void build(int l, int r, int p) {
    31     t[p].l = l, t[p].r = r;
    32     if (l == r) {
    33         t[p].sum = t[p].lmax = t[p].rmax = t[p].maxx = a[l];
    34         return;
    35     }
    36     int mid = (l+r) >> 1;
    37     build(l, mid, ls(p));
    38     build(mid+1, r, rs(p));
    39     push_up(p);
    40 }
    41 
    42 void update(int p, int x, int y) {
    43     if (t[p].l == t[p].r) {
    44         t[p].sum = t[p].lmax = t[p].rmax = t[p].maxx = y;
    45         return;
    46     }
    47     int mid = (t[p].l+t[p].r) >> 1;
    48     if (x <= mid)    update(ls(p), x, y);
    49     else    update(rs(p), x, y);
    50     push_up(p);
    51 }
    52 
    53 T query(int nl, int nr, int p) {
    54     if (nl <= t[p].l && t[p].r <= nr)    return t[p];
    55     T a, b, ans;
    56     a.sum = b.sum = a.lmax = b.lmax = a.rmax = b.rmax = a.maxx = b.maxx = inf;
    57     ans.sum = 0;
    58     int mid = (t[p].l + t[p].r) >> 1;
    59     if (nl <= mid) {
    60         a = query(nl, nr, ls(p));
    61         ans.sum += a.sum;
    62     }
    63     if (mid < nr) {
    64         b = query(nl, nr, rs(p));
    65         ans.sum += b.sum;
    66     }
    67     ans.maxx = max(max(a.maxx, b.maxx), a.rmax+b.lmax);
    68     ans.lmax = max(a.lmax, a.sum+b.lmax);
    69     ans.rmax = max(b.rmax, b.sum+a.rmax);
    70     if (nl > mid)    ans.lmax = max(ans.lmax, b.lmax);
    71     if (nr <= mid)    ans.rmax = max(ans.rmax, a.rmax);
    72     return ans;
    73 }
    74 
    75 int main() {
    76     scanf("%d", &n);
    77 
    78     for (int i = 1; i <= n; i++)
    79         scanf("%d", &a[i]);
    80     build(1, n, 1);
    81 
    82     scanf("%d", &m);
    83     for (int i = 0; i < m; i++) {
    84         int q, x, y;
    85         scanf("%d%d%d", &q, &x, &y);
    86 
    87         if (q) {
    88             if (x > y)    swap(x, y);
    89             printf("%d
    ", query(x, y, 1).maxx);
    90         } else {
    91             update(1, x, y);
    92         }
    93     }
    94 
    95     return 0;
    96 }
    View Code

    UVALive3938,跟上一题基本是同一道题,要改一改。刘汝佳说的对呀,维护sum为啥要用线段树呀233……不过刘汝佳真的query了一大堆……综合刘汝佳和李煜东的优点自己瞎改一下然后莽了一发,还好A了,不然还得痛苦调bug。

      1 #include <cstdio>
      2 #include <climits>
      3 #include <algorithm>
      4 #define ll long long
      5 #define maxn 500001
      6 #define inf LLONG_MAX
      7 #define P pair<int, int>
      8 #define mp make_pair
      9 using namespace std;
     10 
     11 struct Seg {
     12     int l, r;
     13     int max_prefix, max_suffix;
     14     P max_sub; 
     15 }t[maxn<<2];
     16 
     17 int n, m, kase;
     18 ll prefix_sum[maxn];
     19 
     20 ll sum(int l, int r) {
     21     return prefix_sum[r] - prefix_sum[l-1];
     22 }
     23 
     24 ll sum(P y) {
     25     return sum(y.first, y.second);
     26 }
     27 
     28 P better(P a, P b) {
     29     if (sum(a) != sum(b))    return sum(a) > sum(b) ? a : b;
     30     return a < b ? a : b;
     31 }
     32 
     33 void build(int l, int r, int p) {
     34     t[p].l = l, t[p].r = r;
     35     if (l == r) {
     36         t[p].max_prefix = t[p].max_suffix = l;
     37         t[p].max_sub = mp(l, l);
     38         return;
     39     }
     40 
     41     int mid = (l+r) >> 1;
     42     int ls = p << 1, rs = p << 1 | 1;
     43     build(l, mid, ls);
     44     build(mid+1, r, rs);
     45 
     46     ll v1 = sum(l, t[ls].max_prefix);
     47     ll v2 = sum(l, t[rs].max_prefix);
     48     if (v1 == v2)    t[p].max_prefix = t[ls].max_prefix;
     49     else    t[p].max_prefix = v1 > v2 ? t[ls].max_prefix : t[rs].max_prefix;
     50 
     51     v1 = sum(t[ls].max_suffix, r);
     52     v2 = sum(t[rs].max_suffix, r);
     53     if (v1 == v2)    t[p].max_suffix = t[ls].max_suffix;
     54     else    t[p].max_suffix = v1 > v2 ? t[ls].max_suffix : t[rs].max_suffix;
     55 
     56     t[p].max_sub = better(t[ls].max_sub, t[rs].max_sub);
     57     t[p].max_sub = better(t[p].max_sub, mp(t[ls].max_suffix, t[rs].max_prefix));
     58 }
     59 
     60 Seg query(int l, int r, int p) {
     61     if (l <= t[p].l && t[p].r <= r)    return t[p];
     62 
     63     int mid = (t[p].l + t[p].r) >> 1;
     64     int ls = p << 1, rs = p << 1 | 1;
     65 
     66     if (l > mid)    return query(l, r, rs);
     67     if (r <= mid)    return query(l, r, ls);
     68 
     69     Seg a, b, ans;
     70     a = query(l, r, ls);
     71     b = query(l, r, rs);
     72 
     73     ll v1 = sum(l, a.max_prefix), v2 = sum(l, b.max_prefix);
     74     if (v1 == v2)    ans.max_prefix = a.max_prefix;
     75     else    ans.max_prefix = v1 > v2 ? a.max_prefix : b.max_prefix;
     76 
     77     v1 = sum(a.max_suffix, r), v2 = sum(b.max_suffix, r);
     78     if (v1 == v2)    ans.max_suffix = a.max_suffix;
     79     else    ans.max_suffix = v1 > v2 ? a.max_suffix : b.max_suffix;
     80 
     81     ans.max_sub = better(a.max_sub, b.max_sub);
     82     ans.max_sub = better(ans.max_sub, mp(a.max_suffix, b.max_prefix));
     83     return ans;
     84 }
     85 
     86 int main() {
     87     while (~scanf("%d%d", &n, &m)) {
     88         for (int i = 1; i <= n; i++) {
     89             scanf("%lld", &prefix_sum[i]);
     90             prefix_sum[i] += prefix_sum[i-1];
     91         }
     92         build(1, n, 1);
     93         printf("Case %d:
    ", ++kase);
     94         while (m--) {
     95             int l, r;
     96             scanf("%d%d", &l, &r);
     97             P a = query(l, r, 1).max_sub;
     98             printf("%d %d
    ", a.first, a.second);
     99         }
    100     }
    101     return 0;
    102 }
    View Code

    POJ2279,三角形排布是有规律的,可以验证此dp的正确性。

     1 #include <cstdio>
     2 #include <cstring>
     3 #define ll long long
     4 #define init(a, b) memset(a, b, sizeof(a))
     5 #define rep(i, a, b) for (int i = a; i <= b; i++)
     6 
     7 int K, n[6];
     8 
     9 ll solve() {
    10     while (K < 5) {
    11         n[++K] = 0;
    12     }
    13     ll dp[n[1]+1][n[2]+1][n[3]+1][n[4]+1][n[5]+1];
    14     init(dp, 0);
    15     dp[0][0][0][0][0] = 1;
    16 
    17     rep(i, 0, n[1])
    18         rep(j, 0, n[2])
    19             rep(k, 0, n[3])
    20                 rep(s, 0, n[4])
    21                     rep(t, 0, n[5]) {
    22                         ll &cur = dp[i][j][k][s][t];
    23                         if (i < n[1])    dp[i+1][j][k][s][t] += cur;
    24                         if (j < n[2] && j < i)    dp[i][j+1][k][s][t] += cur;
    25                         if (k < n[3] && k < j)    dp[i][j][k+1][s][t] += cur;
    26                         if (s < n[4] && s < k)    dp[i][j][k][s+1][t] += cur;
    27                         if (t < n[5] && t < s)    dp[i][j][k][s][t+1] += cur;
    28                     }
    29     return dp[n[1]][n[2]][n[3]][n[4]][n[5]];
    30 }
    31 
    32 int main() {
    33     while (~scanf("%d", &K) && K) {
    34         rep(i, 1, K)    scanf("%d", &n[i]);
    35         printf("%lld
    ", solve());
    36     }
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    winform 窗体移动API、窗体阴影API
    winform 对话框、打印框
    winform 容器控件
    winform listview控件
    winform 计算器
    Winform 主窗体更换 构造函数传值
    Winform 菜单和工具栏控件
    0103 luffy项目配置
    0102 三大视图配置
    1230 视图家族类
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10340628.html
Copyright © 2011-2022 走看看