zoukankan      html  css  js  c++  java
  • hdu-3397 Sequence operation 线段树多种标记

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=3397

    题目大意:

    0 a b表示a-b区间置为0

    1 a b表示a-b区间置为1

    2 a b表示a-b区间中的0变成1,1变成0

    3 a b表示a-b区间中的1的数目

    4 a b表示a-b区间中最长连续1的长度

    解题思路:

    线段树多种标记。

    需要处理的东西比较多:

    做题的时候发现一个问题:

    我的宏定义Max不可以用于函数,尤其是递归函数,这样会使得同一函数重复调用好几遍,递归函数的话更会超时。

      1 #include<bits/stdc++.h>
      2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
      3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时
      4 #define Min(a, b) ((a) < (b) ? (a) : (b))
      5 #define Mem(a) memset(a, 0, sizeof(a))
      6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
      7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
      8 #define lson ((o)<<1)
      9 #define rson ((o)<<1|1)
     10 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     16     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 typedef long long ll;
     21 const int maxn = 100000 + 10;
     22 const int MOD = 1000000007;//const引用更快,宏定义也更快
     23 
     24 struct node
     25 {
     26     int l, r;//左右区间
     27     int ls0, rs0, ms0;//左连续的0,右连续的0,区间最大连续的0
     28     int ls1, rs1, ms1;//左连续的1,右连续的1,区间最大连续的1
     29     int sum0, sum1;//区间0 1数目
     30     int lazy, Xor;//懒惰标记和异或标记
     31 }tree[maxn << 2];
     32 int a[maxn];
     33 void pushup(int o)
     34 {
     35     if(tree[o].l == tree[o].r)return;//叶子节点直接返回
     36     //根据子节点的信息,更新父节点信息
     37 
     38     //更新0:
     39     int lc = lson, rc = rson;
     40     tree[o].ls0 = tree[lc].ls0;
     41     tree[o].rs0 = tree[rc].rs0;
     42     if(tree[lc].ls0 == tree[lc].r - tree[lc].l + 1)
     43         tree[o].ls0 += tree[rc].ls0;//左节点左连续的0为区间长度 那么根节点左连续的0需要再加上右节点左连续的0
     44     if(tree[rc].rs0 == tree[rc].r - tree[rc].l + 1)
     45         tree[o].rs0 += tree[lc].rs0;
     46     tree[o].ms0 = Max(Max(tree[lc].ms0, tree[rc].ms0), tree[lc].rs0 + tree[rc].ls0);//最大连续0 = Max(左节点最大连续0, 右节点最大连续0,中间最大连续0)
     47     tree[o].sum0 = tree[lc].sum0 + tree[rc].sum0;
     48     //更新1
     49     tree[o].ls1 = tree[lc].ls1;
     50     tree[o].rs1 = tree[rc].rs1;
     51     if(tree[lc].ls1 == tree[lc].r - tree[lc].l + 1)
     52         tree[o].ls1 += tree[rc].ls1;//左节点左连续的0为区间长度 那么根节点左连续的0需要再加上右节点左连续的0
     53     if(tree[rc].rs1 == tree[rc].r - tree[rc].l + 1)
     54         tree[o].rs1 += tree[lc].rs1;
     55     tree[o].ms1 = Max(Max(tree[lc].ms1, tree[rc].ms1), tree[lc].rs1 + tree[rc].ls1);//最大连续0 = Max(左节点最大连续0, 右节点最大连续0,中间最大连续0)
     56     tree[o].sum1 = tree[lc].sum1 + tree[rc].sum1;
     57 }
     58 void XOR(int o)
     59 {
     60     swap(tree[o].ls0, tree[o].ls1);
     61     swap(tree[o].rs0, tree[o].rs1);
     62     swap(tree[o].ms0, tree[o].ms1);
     63     swap(tree[o].sum0, tree[o].sum1);
     64 }
     65 void pushdown(int o)//标记下传
     66 {
     67     if(tree[o].l == tree[o].r)return;
     68     if(tree[o].lazy != -1)//区间覆盖0或者1
     69     {
     70         int lc = lson, rc = rson, len = tree[o].r - tree[o].l + 1;
     71         tree[lc].lazy = tree[rc].lazy = tree[o].lazy;
     72         tree[lc].Xor = tree[rc].Xor = 0;
     73 
     74         //左节点长度为(len+1) / 2 右节点长度为len/2
     75         //
     76         tree[lc].ls0 = tree[lc].rs0 = tree[lc].ms0 = tree[o].lazy ? 0 : (len + 1) / 2;
     77         tree[lc].ls1 = tree[lc].rs1 = tree[lc].ms1 = tree[o].lazy ? (len + 1) / 2 : 0;
     78         tree[lc].sum0 = tree[o].lazy ? 0 : (len + 1) / 2;
     79         tree[lc].sum1 = tree[o].lazy ? (len + 1) / 2 : 0;
     80         //
     81         tree[rc].ls0 = tree[rc].rs0 = tree[rc].ms0 = tree[o].lazy ? 0 : (len) / 2;
     82         tree[rc].ls1 = tree[rc].rs1 = tree[rc].ms1 = tree[o].lazy ? (len) / 2 : 0;
     83         tree[rc].sum0 = tree[o].lazy ? 0 : (len) / 2;
     84         tree[rc].sum1 = tree[o].lazy ? (len) / 2 : 0;
     85 
     86         tree[o].lazy = -1;//清除标记
     87     }
     88     if(tree[o].Xor)
     89     {
     90         tree[o].Xor = 0;
     91         tree[lson].Xor ^= 1;
     92         tree[rson].Xor ^= 1;
     93         XOR(lson), XOR(rson);
     94     }
     95 }
     96 void build(int o, int l, int r)
     97 {
     98     tree[o].l = l, tree[o].r = r, tree[o].lazy = -1, tree[o].Xor = 0;
     99     if(l == r)
    100     {
    101         tree[o].ls0 = tree[o].rs0 = tree[o].ms0 = (a[l] == 0);
    102         tree[o].ls1 = tree[o].rs1 = tree[o].ms1 = (a[l] == 1);
    103         tree[o].sum1 = (a[l] == 1);
    104         tree[o].sum0 = (a[l] == 0);
    105         return;
    106     }
    107     int m = MID(l, r);
    108     build(lson, l, m);
    109     build(rson, m + 1, r);
    110     pushup(o);
    111 }
    112 int flag;//标记类型
    113 int ql, qr;
    114 void update(int o)
    115 {
    116     pushdown(o);
    117     if(ql <= tree[o].l && qr >= tree[o].r)
    118     {
    119         if(flag == 2)
    120         {
    121             tree[o].Xor = 1;
    122             XOR(o);
    123         }
    124         else
    125         {
    126             int len = tree[o].r - tree[o].l + 1;
    127             tree[o].lazy = flag;
    128             tree[o].ls0 = tree[o].rs0 = tree[o].ms0 = flag ? 0 : len;
    129             tree[o].ls1 = tree[o].rs1 = tree[o].ms1 = flag ? len : 0;
    130             tree[o].sum0 = flag ? 0 : len;
    131             tree[o].sum1 = flag ? len : 0;
    132         }
    133     }
    134     else
    135     {
    136         int m = MID(tree[o].l, tree[o].r);
    137         if(ql <= m)update(lson);
    138         if(qr > m)update(rson);
    139         pushup(o);
    140     }
    141 }
    142 
    143 int query(int o)
    144 {
    145     pushdown(o);
    146     if(ql <= tree[o].l && qr >= tree[o].r)
    147     {
    148         if(flag == 3)return tree[o].sum1;
    149         else return tree[o].ms1;
    150     }
    151     else
    152     {
    153         if(qr <= tree[lson].r)return query(lson);
    154         if(ql >= tree[rson].l)return query(rson);
    155         if(flag == 3)return query(lson) + query(rson);
    156         int ans1 = Min(tree[lson].rs1, tree[lson].r - ql + 1) + Min(tree[rson].ls1, qr - tree[rson].l + 1);
    157         int ans2 = max(query(lson), query(rson));//用宏定义会超时,因为一直在递归
    158         return Max(ans1, ans2);
    159     }
    160 }
    161 
    162 int main()
    163 {
    164     int T;
    165     scanf("%d", &T);
    166     while(T--)
    167     {
    168         int n, m;
    169         scanf("%d%d", &n, &m);
    170         for(int i = 1; i <= n; i++)scanf("%d", &a[i]);
    171         build(1, 1, n);
    172         while(m--)
    173         {
    174             scanf("%d%d%d", &flag, &ql, &qr);
    175             ql++, qr++;
    176             if(flag < 3)update(1);
    177             else printf("%d
    ", query(1));
    178         }
    179     }
    180     return 0;
    181 }
  • 相关阅读:
    从零开始入门 K8s | 应用编排与管理
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    203. Remove Linked List Elements
    183. Customers Who Never Order
    182. Duplicate Emails
    181. Employees Earning More Than Their Managers
    1261. Find Elements in a Contaminated Binary Tree
    1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/fzl194/p/9567091.html
Copyright © 2011-2022 走看看