zoukankan      html  css  js  c++  java
  • 区间合并 POJ3667+HDU4553

    两道题都是线段树的区间合并

    lsum, rsum分别表示左/右端点 开始向右/左 符合条件的元素的最长连续长度

    sum表示这个区间的符合条件的元素的最长连续长度

    所以pushUp可写: 

     1 void pushUp(int root, int l, int r)
     2 {
     3     int len = r - l + 1;
     4     int lenr = len >> 1, lenl = len - lenr;
     5     lsum[root] = lsum[lson];
     6     rsum[root] = rsum[rson];
     7     if (lsum[root] == lenl) lsum[root] += lsum[rson];
     8     if (rsum[root] == lenr) rsum[root] += rsum[lson];
     9     sum[root] = max(rsum[lson]+lsum[rson], max(sum[lson], sum[rson])); 
    10 }

    更新时 根据更新的元素的值 可以确定 这个区间的sum lsum 和 rsum 是len 还是 0

    所以pushDown 和 update可以写了

    这里放pushDown

     1 void pushDown(int root, int l, int r)
     2 {
     3     int len = r - l + 1;
     4     int lenr = len >> 1, lenl = len - lenr;
     5     if (setmark[root] != -1)
     6     {
     7         int v = setmark[root];
     8         setmark[lson] = setmark[rson] = v;
     9         setmark[root] = -1; 
    10         lsum[lson] = rsum[lson] = sum[lson] = v ? 0 : lenl;//被占用是1 不被占用是0
    11         lsum[rson] = rsum[rson] = sum[rson] = v ? 0 : lenr;
    12     }
    13 }

    另外注意的是query的方式

    1 int query(int root, int l, int r, int qlen)
    2 {
    3     if (l == r) return l;
    4     pushDown(root, l, r);
    5     int mid = (l+r) >> 1;
    6     if (sum[lson] >= qlen) return query(lson, l, mid, qlen);
    7     else if (rsum[lson]+lsum[rson] >= qlen) return mid-rsum[lson]+1;//左区间的右半部份 和右区间的左半部份 
    8     else if return query(rson, mid+1, r, qlen);
    9 }

    如果不存在直接求sum[1]是否>=qlen

    POJ3667

    元素只有1 和 0两种情况 用一个维护一个区间最长连续和即可

    代码君:

      1 #include <string.h>
      2 #include <stdio.h>
      3 #include <algorithm>
      4 #include <iostream>
      5 #define lson root<<1
      6 #define rson root<<1|1
      7 #define fi first
      8 #define se second
      9 #define pb push_back
     10 #define po pop_back
     11 
     12 typedef long long ll;
     13 
     14 const int MAXN = 50007;
     15 const int MAXM = 50007;
     16 const int INF = 0x3f3f3f3f;
     17 
     18 using namespace std;
     19 
     20 int n, m;
     21 int sum[MAXN << 2];
     22 int setmark[MAXN << 2];
     23 int lsum[MAXN << 2];
     24 int rsum[MAXN << 2];
     25 
     26 void pushUp(int root, int l, int r)
     27 {
     28     int len = r - l + 1;
     29     int lenr = len >> 1, lenl = len - lenr;
     30     lsum[root] = lsum[lson];
     31     rsum[root] = rsum[rson];
     32     if (lsum[root] == lenl) lsum[root] += lsum[rson];
     33     if (rsum[root] == lenr) rsum[root] += rsum[lson];
     34     sum[root] = max(rsum[lson]+lsum[rson], max(sum[lson], sum[rson])); //这个地方 理解!
     35 }
     36 void build(int root, int l, int r)
     37 {
     38     int len = r-l+1;
     39     setmark[root] = -1;
     40     lsum[root] = rsum[root] = sum[root] = len;
     41     if (l == r) return ;
     42     int mid = (l+r) >> 1;
     43     build(lson, l, mid);
     44     build(rson, mid+1, r);
     45     pushUp(root, l, r);
     46 }
     47 void pushDown(int root, int l, int r)
     48 {
     49     int len = r - l + 1;
     50     int lenr = len >> 1, lenl = len - lenr;
     51     if (setmark[root] != -1)
     52     {
     53         int v = setmark[root];
     54         setmark[lson] = setmark[rson] = v;
     55         setmark[root] = -1; 
     56         lsum[lson] = rsum[lson] = sum[lson] = v ? 0 : lenl;//被占用是1 不被占用是0
     57         lsum[rson] = rsum[rson] = sum[rson] = v ? 0 : lenr;
     58     }
     59 }
     60 void update(int root, int l, int r, int ul, int ur, int val)
     61 {
     62     int len = r - l + 1;
     63     int lenr = len >> 1, lenl = len - lenr;
     64     if (l > ur || r < ul) return ;
     65     if (l >= ul && r <= ur)
     66     {
     67         setmark[root] = val;
     68         lsum[root] = rsum[root] = sum[root] = val ? 0 : len;
     69         return ;
     70     }
     71     pushDown(root, l, r);
     72     int mid = (l+r) >> 1;
     73     update(lson, l, mid, ul, ur, val);
     74     update(rson, mid+1, r, ul, ur, val);
     75     pushUp(root, l, r);
     76 }
     77 int query(int root, int l, int r, int qlen)
     78 {
     79     if (l == r) return l;
     80     pushDown(root, l, r);
     81     int mid = (l+r) >> 1;
     82     if (sum[lson] >= qlen) return query(lson, l, mid, qlen);
     83     if (rsum[lson]+lsum[rson] >= qlen) return mid-rsum[lson]+1;//左区间的右半部份 和右区间的左半部份 
     84     if (sum[rson] >= qlen) return query(rson, mid+1, r, qlen);
     85     return -1;
     86 }
     87 int main()
     88 {
     89     //freopen("in.txt", "r", stdin);
     90     while (cin >> n >> m)
     91     {    
     92         build(1, 1, n);
     93         for(int i = 0; i < m; i++)
     94         {
     95             int op, p, l;
     96             scanf("%d", &op);
     97             if (op == 1)
     98             {
     99                 scanf("%d", &l);
    100                 if (sum[1] < l) 
    101                 {
    102                     puts("0");
    103                     continue;
    104                 }
    105                 int pos = query(1, 1, n, l);
    106                 cout << pos << endl;    
    107                 update(1, 1, n, pos, pos+l-1, 1);
    108             }
    109             else
    110             {
    111                 scanf("%d%d", &p, &l);
    112                 //cout << p << " " << p+l-1 << endl;
    113                 update(1, 1, n, p, p+l-1, 0);
    114             }
    115         }
    116     }
    117     return 0;    
    118 }
    View Code

    HDU4553 

    元素有0 1 2三种情况 需要维护两个区间最长连续和

    代码君:

      1 #include <bits/stdc++.h>
      2 #define lson root<<1
      3 #define rson root<<1|1
      4 #define fi first
      5 #define se second
      6 #define pb push_back
      7 #define po pop_back
      8 
      9 using namespace std;
     10 
     11 typedef long long ll;
     12 typedef pair<int, int> P;
     13 
     14 const int MAXN = 1e5+7;
     15 const int MAXM = 1e5+7;
     16 const int INF = 0x3f3f3f3f;
     17 
     18 
     19 
     20 //0 for diaosi  1 for nvshen
     21 int sum[4][MAXN << 2];
     22 int lsum[4][MAXN << 2];
     23 int rsum[4][MAXN << 2];
     24 int setmark[MAXN << 2];
     25 int pos = -1;
     26 int qlen = -1;
     27 int n, m;
     28 void pushUp(int root, int l, int r, int nu)
     29 {
     30     int len = r-l+1;
     31     int lenr = len >> 1, lenl = len - lenr;
     32     lsum[nu][root] = lsum[nu][lson];
     33     if (lsum[nu][root] == lenl) lsum[nu][root] += lsum[nu][rson];
     34     rsum[nu][root] = rsum[nu][rson];
     35     if (rsum[nu][root] == lenr) rsum[nu][root] += rsum[nu][lson];
     36     sum[nu][root] = max(rsum[nu][lson]+lsum[nu][rson], max(sum[nu][lson], sum[nu][rson])); 
     37 }
     38 void build(int root, int l, int r)
     39 {
     40     int len = r - l + 1;
     41     setmark[root] = -1;
     42     for (int i = 0; i < 2; i++) 
     43     {
     44         sum[i][root] = lsum[i][root] = rsum[i][root] = len;
     45     }
     46     if (l == r) return ;
     47     int mid = (l+r) >> 1;
     48     build(lson, l, mid);
     49     build(rson, mid+1, r);
     50     for (int i = 0; i < 2; i++)
     51     pushUp(root, l, r, i);
     52 }
     53 void pushDown(int root, int l, int r)
     54 {
     55     int len = r - l + 1;
     56     int lenr = len >> 1, lenl = len - lenr;
     57     if (setmark[root] != -1)
     58     {
     59         int val = setmark[root];
     60         setmark[lson] = setmark[rson] = val;
     61         setmark[root] = -1;
     62         lsum[0][lson] = rsum[0][lson] = sum[0][lson] = (val == 0 ? lenl : 0);
     63         lsum[0][rson] = rsum[0][rson] = sum[0][rson] = (val == 0 ? lenr : 0);
     64         lsum[1][lson] = rsum[1][lson] = sum[1][lson] = ( (val == 0 || val == 1) ? lenl : 0);  
     65         lsum[1][rson] = rsum[1][rson] = sum[1][rson] = ( (val == 0 || val == 1) ? lenr : 0);
     66     }
     67 }
     68 void update(int root, int l, int r, int ul, int ur, int val)
     69 {
     70     int len = r - l + 1;
     71     if (l > ur || r < ul) return;
     72     if (l >= ul && r <= ur)
     73     {
     74         setmark[root] = val;
     75         lsum[0][root] = rsum[0][root] = sum[0][root] = (val == 0 ? len : 0);
     76         lsum[1][root] = rsum[1][root] = sum[1][root] = ((val == 0 || val == 1) ? len : 0);
     77         return ;
     78     }
     79     pushDown(root, l, r);
     80     int mid = (l+r) >> 1;
     81     update(lson, l, mid, ul, ur, val);
     82     update(rson, mid+1, r, ul, ur, val);
     83     for (int i = 0; i < 2; i++)
     84     pushUp(root, l, r, i);
     85 }
     86 
     87 int query(int root, int l, int r, int qlen, int nu)
     88 {
     89     if (l == r)    return l;
     90     pushDown(root, l, r);
     91     int mid = (l+r) >> 1;
     92     if (sum[nu][lson] >= qlen) return query(lson, l, mid, qlen, nu);
     93     else if (rsum[nu][lson] + lsum[nu][rson] >= qlen) return mid - rsum[nu][lson] + 1; 
     94     else return query(rson, mid+1, r, qlen, nu);
     95 }
     96 int main()
     97 {
     98     //注意都是英文符号
     99     //freopen("in.txt", "r", stdin);
    100     int T;
    101     scanf("%d", &T);
    102     for (int cas = 1; cas <= T; cas++)
    103     {
    104         printf("Case %d:
    ", cas);
    105         scanf("%d%d", &n, &m);
    106         build(1, 1, n);
    107         for (int i = 0; i < m; i++)
    108         {
    109             char buf[32];
    110             int qlen;
    111             scanf("%s", buf);
    112             if (buf[0] == 'D')
    113             {
    114                 scanf("%d", &qlen);
    115                 int pos = -1;
    116                 if (qlen > n || sum[0][1] < qlen) 
    117                 {
    118                     puts("fly with yourself");
    119                     continue;    
    120                 }
    121                 pos = query(1, 1, n, qlen, 0);
    122                 printf("%d,let's fly
    ", pos);
    123                 update(1, 1, n, pos, pos+qlen-1, 1);    
    124             }
    125             else if (buf[0] == 'N')
    126             {
    127                 scanf("%d", &qlen);
    128                 int pos = -1;
    129                 if (qlen > n || sum[1][1] < qlen) 
    130                 {
    131                     puts("wait for me");
    132                     continue;    
    133                 }
    134                 if (sum[0][1] >= qlen) pos = query(1, 1, n, qlen, 0);
    135                 else pos = query(1, 1, n, qlen, 1);
    136                 printf("%d,don't put my gezi
    ", pos);
    137                 update(1, 1, n, pos, pos+qlen-1, 2);    
    138             }
    139             else 
    140             {
    141                 int l, r;
    142                 scanf("%d%d", &l, &r);
    143                 update(1, 1, n, l, r, 0);
    144                 puts("I am the hope of chinese chengxuyuan!!");
    145             }
    146         }
    147     }
    148     return 0;    
    149 }
    View Code
  • 相关阅读:
    shell数组
    Apache HTTP Server 与 Tomcat 的三种连接方式介绍
    实现Java动态类载入机制
    Tomcat 阀
    MYSQL 常用命令
    MYSQL字符数字转换
    主题:MySQL数据库操作实战
    日本手机三大代理商的UA
    Java解析XML文档——dom解析xml (转载)
    MS sql server和mysql中update多条数据的例子
  • 原文地址:https://www.cnblogs.com/oscar-cnblogs/p/8748695.html
Copyright © 2011-2022 走看看