hdu 4391 线段树

来源:互联网 发布:淘宝买沙发靠谱吗 编辑:程序博客网 时间:2024/05/22 00:06

好神啊。解题报告说是哈希,我记得有个人跟我说过分块可以做线段树不能做的,只是复杂度高一点而已。。。。我用线段树过的。。。。。。刚开始把rt << 1写成rt >> 1了,调了一会。。。。。。,后来又T了,于是就开了一个mx和mn记录一个区间中颜色最大的。如果要查询的颜色不在这个区间里面,我们就直接不查了。

/*Pro: 0Sol:date:*/#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <set>#include <vector>#define maxn   100100#define havem int m = (l + r) >> 1#define lson l,m,rt << 1#define rson m+ 1, r, rt << 1|1#define ls rt << 1#define rs rt << 1 | 1using namespace std;int n,m,col[maxn << 2],val[maxn << 2],mx[maxn << 2] ,mn[maxn << 2],op,L,R,c;void push_up(int rt){    if(col[ls] == -1 && col[rs] == -1 && val[ls] == val[rs])  { col[rt] = -1;val[rt] = val[ls]; }    else {  col[rt] = 0; val[rt] = -1; }    mx[rt] = max(mx[ls],mx[rs]);    mn[rt] = min(mn[ls],mn[rs]);}void build(int l, int r, int rt){    if(l == r){        scanf("%d",&val[rt]);        col[rt] = -1;//表示完全覆盖        mn[rt] = mx[rt] = val[rt];        return ;    }havem; build(lson);    build(rson);    push_up(rt);}void push_dn(int rt){    if(col[rt] == -1){        col[ls] = col[rs] = -1;        val[ls] = val[rs] = val[rt];        mx[ls] = mx[rs] = val[rt];        mn[ls] = mn[rs] = val[rt];        col[rt] = 0;    }}void update(int L,int R,int c, int l, int r, int rt){    if(L <= l && r <= R){        col[rt] = -1; val[rt] = c; mx[rt] = c; mn[rt] = c; return ;    }push_dn(rt);   havem;    if(L <= m) update(L,R,c,lson);    if(R > m) update(L,R,c,rson);    push_up(rt);}//T了的话,那么是query的缘故int query(int L,int R,int c, int l, int r, int rt){    if(L <= l && r <= R){        if(col[rt] == -1 && val[rt] == c) return r - l + 1;        else if(c < mn[rt] || c > mx[rt]) return 0;    }//    if(l == r) {//        if(val[rt] == c) return 1;//        else return 0;//    }    push_dn(rt);   havem;    int ans = 0;    if(L <= m) ans = query(L,R,c,lson);    if(R > m) ans += query(L,R,c,rson);    push_up(rt);    return ans;}int main(){    while(~scanf("%d%d",&n,&m)){        build(1,n,1);        for(int i = 0; i < m; i ++){            scanf("%d%d%d%d",&op,&L,&R,&c);            L ++; R ++;            if(op == 1)                update(L,R,c,1,n,1);            else                printf("%d\n",query(L,R,c,1,n,1) );        }    }    return 0;}




原创粉丝点击