HDU-3397-Sequence operation

来源:互联网 发布:mba有用吗 知乎 编辑:程序博客网 时间:2024/05/18 01:36

ACM模版

描述

描述

题解

这道题涉及到的操作有五种,所以处理起来也有些复杂,最起码对于我这种渣来说,是复杂。

对于只有0和1的序列,让我想起来了以前碰见的一个扑克翻面的问题,不过是将0、1替换掉了正反面而已,当然,这个扑克翻面问题只有这个区间染色问题,没有这道题操作这么多,记得不错的话,那是道谷歌面试题……

这里涉及的五种操作分别是:
0:将区间所有值覆盖为0
1:将区间所有值覆盖为1
2:将区间所有值翻转(0和1交换)
3:求区间中所有1的个数
4:求区间中连续最长的1的个数

前两个实际上可以视为一种操作,而2操作实际上是一个异或操作,3是一般的区间操作,我也不知道怎么形容比较合适,4呢,让我想起来前两天做到的一个区间合并问题,求的是区间最长连续递增子序列长度,也就是说这道题是招组合拳,需要见招拆招,一招一招拆,还得考虑到招招之间的关系。

哎,我没事你跟你们瞎掰扯武侠那套了~~~原谅我是金庸迷!

这道题我也不是自己死磕出来的,刚开始做线段树专题训练,好多技巧都不熟(实际上是不会),所以参考了一些大牛们的代码,由于不只是看了一篇大牛们的题解,所以我就不引述了,百度一下,你就知道~~~

代码

#include <iostream>#include <cstdio>#define lson u << 1#define rson u << 1 | 1using namespace std;const int MAXN = 100010;int dat[MAXN];struct node{    int left, right;    int lo, ro, mo; //  1:左端点为起点最长连续数目,右端点为终点最长连续数目,区间最长连续数目    int lz, rz, mz; //  0:左端点为起点最长连续数目,右端点为终点最长连续数目,区间最长连续数目    int res;        //  区间1的个数    int COVER, XOR;} T[MAXN << 2];void makeXOR(int u){   //  翻转操作    swap(T[u].lo, T[u].lz);    swap(T[u].ro, T[u].rz);    swap(T[u].mo, T[u].mz);    T[u].res = T[u].right - T[u].left + 1 - T[u].res;}void PushUp(int u){    if (T[u].left == T[u].right)    {        return ;    }    int len = T[u].right - T[u].left + 1;    T[u].lo = T[lson].lo;    T[u].ro = T[rson].ro;    if (T[u].lo == (len + 1) >> 1)    {        T[u].lo += T[rson].lo;    }    if (T[u].ro == len >> 1)    {        T[u].ro += T[lson].ro;    }    T[u].mo = max(T[lson].mo, T[rson].mo);    T[u].mo = max(T[u].mo, T[lson].ro + T[rson].lo);    T[u].lz = T[lson].lz;    T[u].rz = T[rson].rz;    if (T[u].lz == (len + 1) >> 1)    {        T[u].lz += T[rson].lz;    }    if (T[u].rz == len >> 1)    {        T[u].rz += T[lson].rz;    }    T[u].mz = max(T[lson].mz, T[rson].mz);    T[u].mz = max(T[u].mz, T[lson].rz + T[rson].lz);    T[u].res = T[lson].res + T[rson].res;}void PushDown(int u){    if (T[u].left == T[u].right)    {        return ;    }    if (T[u].COVER != -1)    {        int len = T[u].right - T[u].left + 1;        T[lson].COVER = T[rson].COVER = T[u].COVER;        T[lson].XOR = T[rson].XOR = 0;        T[lson].lo = T[lson].ro = T[lson].mo = T[u].COVER ? (len + 1) >> 1 : 0;        T[lson].lz = T[lson].rz = T[lson].mz = T[u].COVER ? 0 : (len + 1) >> 1;        T[lson].res = T[u].COVER ? (len + 1) >> 1 : 0;        T[rson].lo = T[rson].ro = T[rson].mo = T[u].COVER ? len >> 1 : 0;        T[rson].lz = T[rson].rz = T[rson].mz = T[u].COVER ? 0 : len >> 1;        T[rson].res = T[u].COVER ? len >> 1 : 0;        T[u].COVER = -1;    }    if (T[u].XOR)    {        T[u].XOR = 0;        T[lson].XOR ^= 1;        T[rson].XOR ^= 1;        makeXOR(lson);        makeXOR(rson);    }}void Build(int u, int l, int r){    T[u].left = l;    T[u].right = r;    T[u].COVER = -1;    T[u].XOR = 0;    if (l == r)    {        T[u].lo = T[u].ro = T[u].mo = (dat[l] == 1);        T[u].lz = T[u].rz = T[u].mz = (dat[l] == 0);        T[u].res = dat[l];        T[u].COVER = dat[l];        return ;    }    int mid = (l + r) >> 1;    Build(lson, l, mid);    Build(rson, mid + 1, r);    PushUp(u);}void Update(int u, int l, int r, int op){    PushDown(u);    if (l <= T[u].left && T[u].right <= r)    {        if (op < 2)        {            //  覆盖操作            int len = T[u].right - T[u].left + 1;            T[u].COVER = op;            T[u].lo = T[u].ro = T[u].mo = op ? len : 0;            T[u].lz = T[u].rz = T[u].mz = op ? 0 : len;            T[u].res = op ? len : 0;        }        else        {            T[u].XOR = 1;            makeXOR(u);        }    }    else    {        if (l <= T[lson].right)        {            Update(lson, l, r, op);        }        if (r >= T[rson].left)        {            Update(rson, l, r, op);        }        PushUp(u);    }}int Query(int u, int l, int r, int op){    PushDown(u);    if (l <= T[u].left && T[u].right <= r)    {        if (op == 3)        {            return T[u].res;        }        else        {            return T[u].mo;        }    }    else    {        if (r <= T[lson].right)        {            return Query(lson, l, r, op);        }        if (l >= T[rson].left)        {            return Query(rson, l, r, op);        }        if (op == 3)        {            return Query(lson, l, T[lson].right, op) + Query(rson, T[rson].left, r, op);        }        int ret = min(T[lson].ro, T[lson].right - l + 1) + min(T[rson].lo, r - T[rson].left + 1);        int ans = max(Query(lson, l, T[lson].right, op), Query(rson, T[rson].left, r, op));        return max(ans, ret);    }}int main(){    int t;    scanf("%d", &t);    while (t--)    {        int n, m;        int cmd, a, b;        scanf("%d%d", &n, &m);        for (int i = 1; i <= n; i++)        {            scanf("%d", dat + i);        }        Build(1, 1, n);        while (m--)        {            scanf("%d%d%d", &cmd, &a, &b);            a++, b++;            if (cmd < 3)            {                Update(1, a, b, cmd);            }            else            {                printf("%d\n", Query(1, a, b, cmd));            }        }    }    return 0;}
1 0
原创粉丝点击