zoukankan      html  css  js  c++  java
  • 线段树-各种操作杂烩题 (SCOI2010 DAY2)

    NKOJ2645

    第一次做这种儿子并不一定直接继承父亲节点 lazy ,而要分类讨论的线段树题。学习学习。

      1 #include <stdio.h>
      2 #include <algorithm>
      3 
      4 using namespace std;
      5 
      6 const int _N = 800000;
      7 const int lazy_helper[] = {3, 2, 1, 0};
      8 
      9 int l[_N], r[_N], sum[_N], mx1[_N], mx0[_N], cl1[_N], cl0[_N], cr1[_N], cr0[_N], lazy[_N];
     10 int D, V, S, T, OP, n, m;
     11 
     12 void _build(int p, int s, int t)
     13 {
     14     l[p] = s, r[p] = t;
     15     if (s == t) return;
     16     int mid = s+t>>1;
     17     _build(p<<1, s, mid), _build(p<<1|1, mid+1, t);
     18     return;
     19 }
     20 
     21 void _maintain(int p)
     22 {
     23     int mid = l[p]+r[p] >> 1;
     24     sum[p] = sum[p<<1] + sum[p<<1|1];
     25     mx1[p] = max(max(mx1[p<<1], mx1[p<<1|1]), cr1[p<<1]+cl1[p<<1|1]);
     26     mx0[p] = max(max(mx0[p<<1], mx0[p<<1|1]), cr0[p<<1]+cl0[p<<1|1]);
     27     cl1[p] = mx1[p<<1]==mid-l[p]+1 ? mx1[p<<1]+cl1[p<<1|1] : cl1[p<<1];
     28     cr1[p] = mx1[p<<1|1]==r[p]-mid ? mx1[p<<1|1]+cr1[p<<1] : cr1[p<<1|1];
     29     cl0[p] = mx1[p<<1]==0 ? mid-l[p]+1+cl0[p<<1|1] : cl0[p<<1];
     30     cr0[p] = mx1[p<<1|1]==0 ? r[p]-mid+cr0[p<<1] : cr0[p<<1|1];
     31     return;
     32 }
     33 
     34 inline void _set_1(int p, bool g) { sum[p] = mx1[p] = cl1[p] = cr1[p] = (g ? r[p]-l[p]+1 : 0); return; }
     35 
     36 inline void _set_0(int p, bool g) { mx0[p] = cl0[p] = cr0[p] = (g ? r[p]-l[p]+1 : 0); return; }
     37 
     38 inline void _set(int p, bool g) { _set_1(p, g); _set_0(p, !g); return; }
     39 
     40 inline void _exchange(int p)
     41 {
     42     swap(mx1[p], mx0[p]), swap(cl1[p], cl0[p]), swap(cr1[p], cr0[p]);
     43     sum[p] = r[p]-l[p]+1-sum[p];
     44     return;
     45 }
     46 
     47 //D V
     48 void _modify_single(int p)
     49 {
     50     if (l[p] == r[p]) { _set(p, V); return; }
     51     int mid = l[p]+r[p] >> 1;
     52     if (D <= mid) _modify_single(p<<1);
     53     else _modify_single(p<<1|1);
     54     _maintain(p);
     55     return;
     56 }
     57 
     58 void _pushdown(int p)
     59 {
     60     if (l[p] == r[p]) { lazy[p] = 0; return; }
     61     switch (lazy[p]) {
     62         case 1: _set(p<<1, 0), _set(p<<1|1, 0); break;
     63         case 2: _set(p<<1, 1), _set(p<<1|1, 1); break;
     64         case 3: _exchange(p<<1), _exchange(p<<1|1); break;
     65     }
     66     if (lazy[p] != 3) lazy[p<<1] = lazy[p<<1|1] = lazy[p];
     67     else lazy[p<<1] = lazy_helper[lazy[p<<1]], lazy[p<<1|1] = lazy_helper[lazy[p<<1|1]];
     68     lazy[p] = 0;
     69     return;
     70 }
     71 
     72 //S T OP
     73 void _modify(int p)
     74 {
     75     if (S <= l[p] && r[p] <= T) { _set(p, OP == 2); lazy[p] = OP; return; }
     76     if (lazy[p]) _pushdown(p);
     77     int mid = l[p]+r[p] >> 1;
     78     if (S <= mid && T >= l[p]) _modify(p<<1);
     79     if (S <= r[p] && T > mid) _modify(p<<1|1);
     80     _maintain(p);
     81     return;
     82 }
     83 
     84 //S T OP
     85 void _turnard(int p)
     86 {
     87     if (S <= l[p] && r[p] <= T) { _exchange(p); lazy[p] = lazy_helper[lazy[p]]; return; }
     88     if (lazy[p]) _pushdown(p);
     89     int mid = l[p]+r[p] >> 1;
     90     if (S <= mid && T >= l[p]) _turnard(p<<1);
     91     if (S <= r[p] && T > mid) _turnard(p<<1|1);
     92     _maintain(p);
     93     return;
     94 }
     95 
     96 //S T
     97 int _query_sum(int p)
     98 {
     99     if (S <= l[p] && r[p] <= T) return sum[p];
    100     if (lazy[p]) _pushdown(p);
    101     int mid = l[p]+r[p] >> 1, tmp_cnt = 0;
    102     if (S <= mid && T >= l[p]) tmp_cnt += _query_sum(p<<1);
    103     if (S <= r[p] && T > mid) tmp_cnt += _query_sum(p<<1|1);
    104     return tmp_cnt;
    105 }
    106 
    107 //S T
    108 int _query_con(int p)
    109 {
    110     if (S <= l[p] && r[p] <= T) return mx1[p];
    111     if (lazy[p]) _pushdown(p);
    112     int mid = l[p]+r[p] >> 1, tmp_mx = -1218;
    113     if (S <= mid && T >= l[p]) tmp_mx = max(tmp_mx, _query_con(p<<1));
    114     if (S <= r[p] && T > mid) tmp_mx = max(tmp_mx, _query_con(p<<1|1));
    115     if (S <= mid && T > mid) tmp_mx = max(tmp_mx, min(mid-S+1, cr1[p<<1])+min(T-mid, cl1[p<<1|1]));
    116     return tmp_mx;
    117 }
    118 
    119 int main()
    120 {
    121     int i;
    122     scanf("%d%d", &n, &m);
    123     _build(1, 1, n);
    124     for (i = 1; i <= n; ++i) {
    125         scanf("%d", &V);
    126         D = i, _modify_single(1);
    127     }
    128     while (m--) {
    129         scanf("%d%d%d", &OP, &S, &T), ++S, ++T, ++OP;
    130         if (OP == 1 || OP == 2) { _modify(1); continue; }
    131         if (OP == 3) { _turnard(1); continue; }
    132         if (OP == 4) { printf("%d
    ", _query_sum(1)); continue; }
    133         if (OP == 5) { printf("%d
    ", _query_con(1)); continue; }
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    dom4j解析XML时忽略DTD文件,加速文件解析过程
    mysql 中 in 语句参数个数
    N皇后 java
    springboot+jpa多表查询
    使用lua脚本在nginx上进行灰度流量转发
    RestTemplate将字符串以文件的方式上传
    在idea中编写自动拉取、编译、启动springboot项目的shell脚本
    逻辑回归调优方向
    流程图采用mindmanager进行绘制相关流程图体验较好
    尝试使用utool进行一些任务管理,例如ocr功能,使用讯飞ocr可以提高效率,替换图床
  • 原文地址:https://www.cnblogs.com/ghcred/p/8296101.html
Copyright © 2011-2022 走看看