hdu 3974 线段树

线段树,区间更新,单点询问。

一个序列。

更新:T a b , 将a所对应的区间的值都改成b

询问:C a,问a的值是多少?

做题过程:

        哎,又开始漫漫找错路。。。

        原来这题是要自己找根的。原来写的lazy操作是对的,wa了之后我就将lazy那个数组直接删了,当时我想val它自己就相当于一个lazy操作,结果样例肿么都过不了。不得已,手写样例。发觉是需要lazy这个数组的,它来记录val[rt]这个值是否覆盖整个区间

    /*
    Pro: 0

    Sol:

    date:
    */
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <vector>
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    #define havem int m = (l + r ) >> 1
    #define maxn 50010
    using namespace std;
    int t, n, Q, head[maxn],L[maxn], R[maxn],li,sub,is[maxn];
    int val[maxn << 2], lazy[maxn << 2];
    char op[10];
    void init(){
        memset(L,0,sizeof(L));
        memset(head, -1, sizeof(head));
        memset(is,0,sizeof(is));
        sub = li = 0;
    }
    void build(int l, int r, int rt){
        lazy[rt] = 0;   val[rt] = -1;
        if(l == r)  return ;
        havem;
        build(lson); build(rson);
    }
    struct Edge{
        int v,nxt;
    }edge[maxn << 1];//
    void add(int u, int v){
        edge[sub].v = v;
        edge[sub].nxt = head[u];
        head[u] = sub ++;
    }
    void dfs(int rt){
        L[rt] = ++li;//从1开始建
        for(int j = head[rt]; j != -1; j = edge[j].nxt){
            if(!L[edge[j].v])   dfs(edge[j].v);
        }
        R[rt] = li;
    }
    void push_dn(int rt){
        if(lazy[rt]){
            val[rt << 1] = val[rt << 1 | 1] = lazy[rt];
            lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
            lazy[rt] = 0;
        }
    }
    void update(int& L,int & R, int& cc, int l, int r, int rt){
        if(L <= l && r <= R){
            lazy[rt] = cc; val[rt] = cc; return ;
        }push_dn(rt);
        havem;
        if(L <= m) update(L,R,cc,lson);
        if(R > m) update(L,R,cc,rson);
    }
    int query(int& pos , int l, int r, int rt){
        if(l == r) return val[rt];
        push_dn(rt); havem;
        if(pos <= m) return query(pos,lson);
        else return query(pos,rson);
    }
    int main(){
        scanf("%d",&t); int a, b;
        for(int ca = 1; ca <= t; ca ++){
            printf("Case #%d:\n",ca);
            init();
            scanf("%d",&n);
            for(int i = 0; i < n - 1; i ++){
                scanf("%d%d",&a,&b);
    //            add(a,b);
                add(b, a);
                is[a] ++;
            }
            for(int i = 1; i <= n; i ++)
                if(!is[i]) {dfs(i); break;}
    //        for(int i = 1; i <= n; i ++)
    //            cout << i << "  ** " << R[i]  << endl;

            build(1,n,1);
            scanf("%d",&Q);
            for(int i =0 ; i < Q; i ++){
                scanf("%s",op);
                if(op[0] == 'C'){
                    scanf("%d",&a);
                    printf("%d\n",query(L[a],1,n,1));
                }else{
                    scanf("%d%d",&a,&b);
                    update(L[a],R[a],b,1,n,1);
                }
            }
        }
        return 0;
    }


你可能感兴趣的:(hdu 3974 线段树)