• 数据结构专题测试 2017.4.4



      打两个lazy标记,覆盖操作(modify),把mlazy改为x,clazy改为0,增加操作(change),把clazy增加x。pushDown时候先更新mlazy,再更新clazy。

      但是数据有些问题(然后十个点全崩掉了),l > r的情况修改操作无视,查询操作输出0。

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<ctime>
      4 #include<cctype>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<fstream>
      8 #include<sstream>
      9 #include<algorithm>
     10 #include<map>
     11 #include<set>
     12 #include<stack>
     13 #include<queue>
     14 #include<vector>
     15 #include<stack>
     16 #ifndef WIN32
     17 #define AUTO "%lld"
     18 #else
     19 #define AUTO "%I64d"
     20 #endif
     21 using namespace std;
     22 typedef bool boolean;
     23 #define inf 0xfffffff
     24 #define llf    (1LL << 60)
     25 #define smin(a, b) a = min(a, b)
     26 #define smax(a, b) a = max(a, b)
     27 #define max3(a, b, c) max(a, max(b, c))
     28 #define min3(a, b, c) min(a, min(b, c))
     29 template<typename T>
     30 inline boolean readInteger(T& u){
     31     char x;
     32     int aFlag = 1;
     33     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     34     if(x == -1) {
     35         ungetc(x, stdin);
     36         return false;
     37     }
     38     if(x == '-'){
     39         x = getchar();
     40         aFlag = -1;
     41     }
     42     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     43     ungetc(x, stdin);
     44     u *= aFlag;
     45     return true;
     46 }
     47 
     48 typedef class SegTreeNode {
     49     public:
     50         long long val;
     51         SegTreeNode *l, *r;
     52         long long clazy;
     53         long long mlazy;
     54         SegTreeNode(int val = 0, SegTreeNode* l = NULL, SegTreeNode* r = NULL, long long mlazy = llf, long long clazy = 0):val(val), l(l), r(r), mlazy(mlazy), clazy(clazy) {        }
     55 
     56         inline void pushUp() {
     57             this->val = l->val + r->val;
     58         }
     59         
     60         inline void pushmDown(int le, int ri, int mid) {
     61             l->val = (mid - le + 1) * mlazy;
     62             r->val = (ri - mid) * mlazy;
     63             l->mlazy = r->mlazy = mlazy;
     64             l->clazy = r->clazy = 0;
     65             mlazy = llf;
     66         }
     67         
     68         inline void pushcDown(int le, int ri, int mid) {
     69             l->val += (mid - le + 1) * clazy;
     70             r->val += (ri - mid) * clazy;
     71             l->clazy += clazy, r->clazy += clazy;
     72             clazy = 0;
     73         }
     74 }SegTreeNode;
     75 
     76 typedef class SegTree {
     77     public:
     78         SegTreeNode* root;
     79         
     80         SegTree():root(NULL) {        }
     81         SegTree(int s, int* lis) {
     82             build(root, 1, s, lis);
     83         }
     84         
     85         void build(SegTreeNode*& node, int l, int r, int* lis) {
     86             node = new SegTreeNode();
     87             if(l == r) {
     88                 node->val = lis[l];
     89                 return;
     90             }
     91             int mid = (l + r) >> 1;
     92             build(node->l, l, mid, lis);
     93             build(node->r, mid + 1, r, lis);
     94             node->pushUp();
     95         }
     96         
     97         void modify(SegTreeNode*& node, int l, int r, int ml, int mr, int x) {
     98             if(l == ml && r == mr) {
     99                 node->val = (r - l + 1) * 1LL * x;
    100                 node->mlazy = x, node->clazy = 0;
    101                 return;
    102             }
    103             int mid = (l + r) >> 1;
    104             if(node->mlazy != llf) node->pushmDown(l, r, mid);
    105             if(node->clazy)    node->pushcDown(l, r, mid);
    106             if(mr <= mid)    modify(node->l, l, mid, ml, mr, x);
    107             else if(ml > mid)    modify(node->r, mid + 1, r, ml, mr, x);
    108             else {
    109                 modify(node->l, l, mid, ml, mid, x);
    110                 modify(node->r, mid + 1, r, mid + 1, mr, x);
    111             }
    112             node->pushUp();
    113         }
    114         
    115         void update(SegTreeNode*& node, int l, int r, int ml, int mr, int x) {
    116             if(l == ml && r == mr) {
    117                 node->val += (r - l + 1) * 1LL * x;
    118                 node->clazy += x;
    119                 return;
    120             }
    121             int mid = (l + r) >> 1;
    122             if(node->mlazy != llf) node->pushmDown(l, r, mid);
    123             if(node->clazy)    node->pushcDown(l, r, mid);
    124             if(mr <= mid)    update(node->l, l, mid, ml, mr, x);
    125             else if(ml > mid)    update(node->r, mid + 1, r, ml, mr, x);
    126             else {
    127                 update(node->l, l, mid, ml, mid, x);
    128                 update(node->r, mid + 1, r, mid + 1, mr, x);
    129             }
    130             node->pushUp();
    131         }
    132         
    133         long long query(SegTreeNode*& node, int l, int r, int ql, int qr) {
    134             if(l == ql && r == qr) {
    135                 return node->val;
    136             }
    137             int mid = (l + r) >> 1;
    138             if(node->mlazy != llf) node->pushmDown(l, r, mid);
    139             if(node->clazy)    node->pushcDown(l, r, mid);
    140             if(qr <= mid)    return query(node->l, l, mid, ql, qr);
    141             if(ql > mid)    return query(node->r, mid + 1, r, ql, qr);
    142             return query(node->l, l, mid, ql, mid) + query(node->r, mid + 1, r, mid + 1, qr);
    143         }
    144 }SegTree;
    145 
    146 int n, m;
    147 int* lis;
    148 SegTree st;
    149 
    150 inline void init() {
    151     readInteger(n);
    152     readInteger(m);
    153     lis = new int[(const int)(n + 1)];
    154     for(int i = 1; i <= n; i++) {
    155         readInteger(lis[i]);
    156     }
    157     st = SegTree(n, lis);
    158 }
    159 
    160 char s[11];
    161 inline void solve() {
    162     int a, b, x;
    163     while(m--) {
    164         scanf("%s", s);
    165         readInteger(a);
    166         readInteger(b);
    167         if(s[0] == 'm') {
    168             readInteger(x);
    169             if(a > b)    continue;
    170             st.modify(st.root, 1, n, a, b, x);
    171         } else if(s[0] == 'c') {
    172             readInteger(x);
    173             if(a > b)    continue;
    174             st.update(st.root, 1, n, a, b, x);
    175         } else {
    176             if(a > b)    printf("0
    ");
    177             else {
    178                 long long res = st.query(st.root, 1, n, a, b);
    179                 printf(AUTO"
    ", res);
    180             }
    181         }
    182     }
    183 }
    184 
    185 int main() {
    186     freopen("setmod.in", "r", stdin);
    187     freopen("setmod.out", "w", stdout);
    188     init();
    189     solve();
    190     return 0;
    191 }


      将平行于x轴的线段按y值排序,然后扫描线加线段树辅助。

      线段树的节点记录cov,sum。cov表示该节点代表的区间被完全覆盖的次数,sum表示在该区间内被覆盖的长度。

      更新时先判断cov是否非0,如果是,则sum = r - l + 1,否则用左右子树的值去更新它。

      当扫描线扫描到下边界时,将它加入线段树,否则再线段树中将它删除。每次处理完一个y值的边,就给答案加上根节点的sum值乘上和下一条线段的y值的差值。

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<ctime>
      4 #include<cctype>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<fstream>
      8 #include<sstream>
      9 #include<algorithm>
     10 #include<map>
     11 #include<set>
     12 #include<stack>
     13 #include<queue>
     14 #include<vector>
     15 #include<stack>
     16 #ifndef WIN32
     17 #define AUTO "%lld"
     18 #else
     19 #define AUTO "%I64d"
     20 #endif
     21 using namespace std;
     22 typedef bool boolean;
     23 #define inf 0xfffffff
     24 #define llf    (1LL << 60)
     25 #define smin(a, b) a = min(a, b)
     26 #define smax(a, b) a = max(a, b)
     27 #define max3(a, b, c) max(a, max(b, c))
     28 #define min3(a, b, c) min(a, min(b, c))
     29 template<typename T>
     30 inline boolean readInteger(T& u){
     31     char x;
     32     int aFlag = 1;
     33     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     34     if(x == -1) {
     35         ungetc(x, stdin);
     36         return false;
     37     }
     38     if(x == '-'){
     39         x = getchar();
     40         aFlag = -1;
     41     }
     42     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     43     ungetc(x, stdin);
     44     u *= aFlag;
     45     return true;
     46 }
     47 
     48 typedef class SegTreeNode {
     49     public:
     50         int cov;    //被完整覆盖的次数 
     51         int sum;    //被覆盖的长度 
     52         SegTreeNode *l, *r;
     53         
     54         SegTreeNode(int cov = 0, int sum = 0, SegTreeNode* l = NULL, SegTreeNode* r = NULL):cov(cov), sum(sum), l(l), r(r) {    }
     55         
     56         inline void pushUp(int lg, int rt) {
     57             if(cov)    sum = rt - lg + 1;
     58             else if(lg == rt)    sum = 0;
     59             else sum = l->sum + r->sum; 
     60         }
     61 }SegTreeNode;
     62 
     63 typedef class SegTree {
     64     public:
     65         SegTreeNode* root;
     66         
     67         SegTree():root(NULL) {        }
     68         SegTree(int s) {
     69             build(root, 1, s);
     70         }
     71         
     72         void build(SegTreeNode*& node, int l, int r) {
     73             node = new SegTreeNode();
     74             if(l == r)    return;
     75             int mid = (l + r) >> 1;
     76             build(node->l, l, mid);
     77             build(node->r, mid + 1, r);
     78         }
     79         
     80         void update(SegTreeNode*& node, int l, int r, int le, int ri, int val) {
     81             if(l == le && r == ri) {
     82                 node->cov += val;
     83                 node->pushUp(l, r);
     84                 return;
     85             }
     86             int mid = (l + r) >> 1;
     87             if(ri <= mid)    update(node->l, l, mid, le, ri, val);
     88             else if(le > mid)    update(node->r, mid + 1, r, le, ri, val);
     89             else {
     90                 update(node->l, l, mid, le, mid, val);
     91                 update(node->r, mid + 1, r, mid + 1, ri, val);
     92             }
     93             node->pushUp(l, r);
     94         }
     95         
     96         int query() {
     97             return root->sum;
     98         }
     99 }SegTree;
    100 
    101 typedef class Line {
    102     public:
    103         int x0, x1;
    104         int y;
    105         int side;
    106         Line(int x0 = 0, int x1 = 0, int y = 0, int side = 0):x0(x0), x1(x1), y(y), side(side) {        }
    107         
    108         boolean operator < (Line b) const {
    109             if(y != b.y)    return y < b.y;
    110             if(x0 != b.x0)    return x0 < b.x0;
    111             return x1 < b.x1;
    112         }
    113 }Line;
    114 
    115 int n;
    116 Line* lines;
    117 int valx = 0, minx = inf;
    118 
    119 inline void init() {
    120     readInteger(n);
    121     lines = new Line[(2 * n + 1)];
    122     for(int i = 1, x0, x1, y0, y1; i <= n; i++) {
    123         readInteger(x0);
    124         readInteger(y0);
    125         readInteger(x1);
    126         readInteger(y1);
    127         lines[2 * i - 1] = Line(x0, x1, y0, 1);
    128         lines[2 * i] = Line(x0, x1, y1 + 1, -1);
    129         smax(valx, x1);
    130     }
    131 }
    132 
    133 SegTree st;
    134 long long res = 0;
    135 inline void solve() {
    136     st = SegTree(valx + 1);
    137     sort(lines + 1, lines + 2 * n + 1);
    138     for(int i = 1; i <= 2 * n;) {
    139         int cmp = lines[i].y;
    140         while(i <= 2 * n && lines[i].y == cmp) {
    141             st.update(st.root, 1, valx, lines[i].x0, lines[i].x1, lines[i].side);
    142             i++;
    143         }
    144         res += st.query() * 1LL * (lines[i].y - cmp);
    145     }
    146     printf(AUTO, res);
    147 }
    148 
    149 int main() {
    150     freopen("area.in", "r", stdin);
    151     freopen("area.out", "w", stdout);
    152     init();
    153     solve();
    154     return 0;
    155 }


      带修改的主席树裸题。

      只不过因为数据范围比较大,动态开节点变成了,先开一堆节点然后慢慢分配(此方法被称为开内存池),vector也不能用,手写一个数组,不然会超时。

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<ctime>
      4 #include<cctype>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<fstream>
      8 #include<sstream>
      9 #include<algorithm>
     10 #include<map>
     11 #include<set>
     12 #include<stack>
     13 #include<queue>
     14 #include<vector>
     15 #include<stack>
     16 #ifndef WIN32
     17 #define AUTO "%lld"
     18 #else
     19 #define AUTO "%I64d"
     20 #endif
     21 using namespace std;
     22 typedef bool boolean;
     23 #define inf 0xfffffff
     24 #define llf    (1LL << 60)
     25 #define smin(a, b) a = min(a, b)
     26 #define smax(a, b) a = max(a, b)
     27 #define max3(a, b, c) max(a, max(b, c))
     28 #define min3(a, b, c) min(a, min(b, c))
     29 template<typename T>
     30 inline boolean readInteger(T& u){
     31     char x;
     32     int aFlag = 1;
     33     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     34     if(x == -1) {
     35         ungetc(x, stdin);
     36         return false;
     37     }
     38     if(x == '-'){
     39         x = getchar();
     40         aFlag = -1;
     41     }
     42     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     43     ungetc(x, stdin);
     44     u *= aFlag;
     45     return true;
     46 }
     47 
     48 typedef class SegTreeNode {
     49     public:
     50         int s;
     51         SegTreeNode *l, *r;
     52         SegTreeNode(int s = 0, SegTreeNode* l = NULL, SegTreeNode* r = NULL):s(s), l(l), r(r) {        }
     53         
     54         inline void pushUp() {
     55             this->s += l->s + r->s;
     56         }
     57 }SegTreeNode;
     58 
     59 SegTreeNode nul = SegTreeNode(0, &nul, &nul);
     60 SegTreeNode *top;
     61 SegTreeNode* pool;
     62 #define lowbit(x) (x & (-x))
     63 
     64 template<typename T>
     65 class List {
     66     public:
     67         T* lis;
     68         int top;
     69         
     70         List():lis(NULL), top(0) {        }
     71         List(int s):top(0) {
     72             lis = new T[(const int)(s + 1)];
     73         }
     74 //        ~List() {
     75 //            delete[] lis;
     76 //        }
     77         
     78         void push_back(T x) {    lis[top++] = x;    }
     79         int size() {    return top;        }
     80         void clear() {    top = 0;        }
     81         
     82         T& operator [] (int pos) {
     83             return lis[pos];
     84         }
     85 };
     86 
     87 typedef class ChairTree {
     88     public:
     89         int size;
     90         int* a;
     91         SegTreeNode** lis;
     92         List<SegTreeNode*> sum, csum;
     93         List<SegTreeNode*> nodes;
     94         
     95         SegTreeNode* newNode() {
     96             top->l = &nul;
     97             top->r = &nul;
     98             top->s = 0;
     99             return top++;
    100         }
    101         
    102         ChairTree():size(0) {        }
    103         ChairTree(int s, int* a):size(s), a(a) {
    104             lis = new SegTreeNode*[(const int)(s + 1)];
    105             sum = List<SegTreeNode*>(s + 10);
    106             csum = List<SegTreeNode*>(s + 10);
    107             nodes = List<SegTreeNode*>(s + 10);
    108             for(int i = 0; i <= s; i++)
    109                 lis[i] = newNode();
    110             for(int i = 1; i <= s; i++) {
    111                 for(int j = i; j <= size; j += lowbit(j))
    112                     modify(lis[j], 1, size, a[i], 1);
    113             }
    114         }
    115         
    116         void modify(SegTreeNode*& node, int l, int r, int idx, int val) {
    117             if(node == &nul)
    118                 node = newNode();
    119             node->s += val;
    120             if(l == idx && r == idx) {
    121                 return;
    122             }
    123             int mid = (l + r) >> 1;
    124             if(idx <= mid)    modify(node->l, l, mid, idx, val);
    125             else modify(node->r, mid + 1, r, idx, val);
    126         }
    127         
    128         inline void modify(int idx, int x) {
    129             for(int i = idx; i <= size; i += lowbit(i))    modify(lis[i], 1, size, a[idx], -1);
    130             a[idx] = x;
    131             for(int i = idx; i <= size; i += lowbit(i))    modify(lis[i], 1, size, a[idx], 1);
    132         }
    133         
    134         int query(List<SegTreeNode*>& sum, List<SegTreeNode*>& csum, int l, int r, int k) {
    135             if(l == r)    return l;
    136             int mid = (l + r) >> 1;
    137             int s1 = sum.size(), s2 = csum.size();
    138             int ls = 0;
    139             for(int i = 0; i < s1; i++)    ls += sum[i]->l->s;
    140             for(int i = 0; i < s2; i++)    ls -= csum[i]->l->s;
    141             if(k <= ls) {
    142                 for(int i = 0; i < s1; i++)    sum[i] = sum[i]->l;
    143                 for(int i = 0; i < s2; i++)    csum[i] = csum[i]->l;
    144                 return query(sum, csum, l, mid, k);
    145             }
    146             for(int i = 0; i < s1; i++)    sum[i] = sum[i]->r;
    147             for(int i = 0; i < s2; i++)    csum[i] = csum[i]->r;
    148             return query(sum, csum, mid + 1, r, k - ls);
    149         }
    150         
    151         int query(int l, int r, int k) {
    152             sum.clear(), csum.clear();
    153             for(int i = r; i; i -= lowbit(i))    sum.push_back(lis[i]);
    154             for(int i = l - 1; i; i -= lowbit(i))    csum.push_back(lis[i]);
    155             return query(sum, csum, 1, size, k);
    156         }
    157 }ChairTree;
    158 
    159 int n, m;
    160 int* lis;
    161 ChairTree ct;
    162 
    163 inline void init() {
    164     readInteger(n);
    165     readInteger(m);
    166     lis = new int[(const int)(n + 1)];
    167     for(int i = 1; i <= n; i++)
    168         readInteger(lis[i]);
    169 }
    170 
    171 char s[10];
    172 inline void solve() {
    173     pool = new SegTreeNode[(n * 200)];
    174     top = pool;
    175     int a, b, c;
    176     ct = ChairTree(n, lis);
    177     while(m--) {
    178         scanf("%s", s);
    179         readInteger(a);
    180         readInteger(b);
    181         if(s[0] == 'm') {
    182             ct.modify(a, b);
    183         } else {
    184             readInteger(c);
    185             int x = ct.query(a, b, c);
    186             printf("%d
    ", x);
    187         }
    188     }
    189 }
    190 
    191 int main() {
    192     freopen("intkth.in", "r", stdin);
    193     freopen("intkth.out", "w", stdout);
    194     init();
    195     solve();
    196     return 0;
    197 }
  • 相关阅读:
    解决docker 容器删除不掉的问题
    centos下安装docker
    Microsoft SQL Server 双机热备份,实时同步
    同一台主机下的两台虚拟机互ping不通
    JAVA基本数据类型
    记录一些比较高能的网站!
    Nginx+Lua+Redis配置
    用Squid3搭建缓存代理服务器
    Mysql导入CSV文件
    LeetCode--Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6669740.html
Copyright © 2020-2023  润新知