HDU1540--线段树(最长连续区间)

来源:互联网 发布:java float与double 编辑:程序博客网 时间:2024/05/21 18:43

这个题目好像不是很难,可是我想了很久,还超时了。。我用的是普通线段树和二分,第一次用二分超时啊啊啊啊啊

好,让我们言归正传。(参考别的大佬的做法,贼6)

看到这个题目之后,能够想到它是为了求包含一个点的最大连续区间。那么多的区间,应该是要用线段树来做。

可以想得到,查询的时候,是从这个点展开,判断左右是否连续。

首先,我们用递归查询到这个点,或者说是包含这个点的连续区间,假设它是一个左子树,那我们就要加上它相邻的右子树的从左边开始的连续区间,如果它是右子树,那么就按相反。

这样的话,我们不如就建立两个数组,一个是从左边开始累加区间长度的数组(lsum[]),一个是从右边开始累加区间长度的数组(rsum[]),然后建树,更新节点,查询。

还要提一点,由于题目中有一个什么重建,emmm,就是先进后出的栈嘛,所以我们这里就可以用到c++中的一个stack容器

有这几个常用的操作吧:

stack<int> s;

1.入栈:如s.push(x);

2.出栈:如 s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。

3.访问栈顶:如s.top();

4.判断栈空:如s.empty().当栈空时返回true。

5.访问栈中的元素个数,如s.size();

贴代码:

#include"cstdio"#include"stack"using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 50010int lsum[4*maxn],rsum[4*maxn],flag;void Build(int l,int r,int rt) {    lsum[rt] = rsum[rt] = r-l+1;    if (l == r) return;    int m = (l+r) >> 1;    Build(lson);    Build(rson);}void Pushup(int rt,int m) {    lsum[rt] = lsum[rt<<1];    rsum[rt] = rsum[rt<<1|1];    if (lsum[rt] == m - (m>>1)) lsum[rt] += lsum[rt<<1|1];//yi cuo    if (rsum[rt] == m>>1) rsum[rt] += rsum[rt<<1];}void Updata(int p,int x,int l,int r,int rt) {    if (l == r) {        lsum[rt] = rsum[rt] = x;        return;    }    int m = (l+r) >> 1;    if (p <= m) Updata(p,x,lson); else Updata(p,x,rson);    Pushup(rt,r-l+1);}int Query(int p,int l,int r,int rt) {    if (rsum[rt] >= r-p+1) {        flag = 1;        return rsum[rt];    }    if (lsum[rt] >= p-l+1) {        flag = 1;        return lsum[rt];    }    if (l == r) return 0;    int m = (l+r) >> 1, t = 0;    if (p > m) {        t = Query(p,rson);        if (flag) {            flag = 0;            t += rsum[rt<<1];        }    } else {        t = Query(p,lson);        if (flag) {            flag = 0;            t += lsum[rt<<1|1];        }    }    return t;}int main() {    int n,m;//    freopen("1.in","r",stdin);    while(~scanf("%d%d",&n,&m)) {        Build(1,n,1);        char cmd[2];        stack<int> sta;        for (int i = 0;i < m;i ++) {            scanf("%s",cmd);            if (cmd[0] == 'D') {                int x;                scanf("%d",&x);                sta.push(x);                Updata(sta.top(),0,1,n,1);            } else            if (cmd[0] == 'Q') {                int x;                flag = 0;                scanf("%d",&x);                printf("%d\n",Query(x,1,n,1));            } else {                Updata(sta.top(),1,1,n,1);                sta.pop();            }        }    }    return 0;}




原创粉丝点击