zoukankan      html  css  js  c++  java
  • 线段树专题

    ①POJ3667

    题目链接:http://poj.org/problem?id=3667

    思路:pushup为合并,向上更新。pushdown为向下更新,lazy存放待更新的操作,1为置满,0为无操作,-1为置空。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 5e4 + 5;
    struct node
    {
        int l,r,lazy,ls,rs,ms;
    }tree[N<<2];
    void pushup(int i)
    {
        int mid = (tree[i].l + tree[i].r) >> 1;
        if(tree[i*2].ls == mid - tree[i].l + 1)
            tree[i].ls = tree[i*2].ls + tree[i*2 + 1].ls;
        else
            tree[i].ls = tree[i*2].ls;
        if(tree[i*2 + 1].rs == tree[i].r - mid)
            tree[i].rs = tree[i*2 + 1].rs + tree[i*2].rs;
        else
            tree[i].rs = tree[i*2 + 1].rs;
        tree[i].ms = max(max(tree[i*2].ms,tree[i*2 + 1].ms),tree[i*2].rs + tree[i*2 + 1].ls);
    }
    void pushdown(int i)
    {
        if(tree[i].lazy)
        {
            tree[i*2].lazy = tree[i*2 + 1].lazy = tree[i].lazy;
            if(tree[i].lazy == 1)
            {
                tree[i*2].ls = tree[i*2].rs = tree[i*2].ms = 0;
                tree[i*2 + 1].ls = tree[i*2 + 1].rs = tree[i*2 + 1].ms = 0;
            }
            else
            {
                tree[i*2].ls = tree[i*2].rs = tree[i*2].ms = tree[i*2].r - tree[i*2].l + 1;
                tree[i*2 + 1].ls = tree[i*2 + 1].rs = tree[i*2 + 1].ms = tree[i*2 + 1].r - tree[i*2 + 1].l + 1;
            }
            tree[i].lazy = 0;
        }
    }
    void built(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].lazy = 0;
        tree[i].ls = tree[i].rs = tree[i].ms = r - l + 1;
        if(l == r)
            return;
        int mid = (l + r) >> 1;
        built(i*2,l,mid);
        built(i*2 + 1,mid + 1,r);
    }
    void update(int i,int l,int r,int c)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            tree[i].lazy = c;
            if(c == 1)
                tree[i].ls = tree[i].rs = tree[i].ms = 0;
            else
                tree[i].ls = tree[i].rs = tree[i].ms = tree[i].r - tree[i].l + 1;
            return;
        }
        if(tree[i].r < l || tree[i].l > r)
            return;
        pushdown(i);
        update(i*2,l,r,c);
        update(i*2 + 1,l,r,c);
        pushup(i);
    }
    int query(int i,int len)
    {
        pushdown(i);
        if(tree[i].ls >= len)
            return tree[i].l;
        if(tree[i*2].ms >= len)
            return query(i*2,len);
        if(tree[i*2].rs + tree[i*2 + 1].ls >= len)
        {
            int mid = (tree[i].l + tree[i].r) >> 1;
            return mid - tree[i*2].rs + 1;
        }
        return query(i*2 + 1,len);
    }
    int main()
    {
        int n,m;
        while(~scanf("%d %d",&n,&m))
        {
            built(1,1,n);
            while(m--)
            {
                int c;
                scanf("%d",&c);
                if(c == 1)
                {
                    int x;
                    scanf("%d",&x);
                    if(tree[1].ms < x)
                    {
                        puts("0");
                        continue;
                    }
                    int ans = query(1,x);
                    printf("%d
    ",ans);
                    update(1,ans,ans + x - 1,1);
                }
                else
                {
                    int x,y;
                    scanf("%d %d",&x,&y);
                    update(1,x,x + y - 1,-1);
                }
            }
        }
        return 0;
    }
    

      

    ②POJ3225

    题目链接:http://poj.org/problem?id=3225

    #include<cstdio>
    #define le(i) i<<1
    #define ri(i) i<<1|1
    using namespace std;
    const int N = 65535 << 1;
    struct node
    {
        int l,r,lazy,cov;//lazy表示操作:2为互换,1为置满,0为置空,-1为无操作。cov表示状态:1为全包含,0为全不包含,-1为其它
    }tree[(N<<2)+5];
    int s[(N<<1)+5];
    void pushup(int i)
    {
        if(tree[le(i)].cov == tree[ri(i)].cov)
            tree[i].cov = tree[le(i)].cov;
        else
            tree[i].cov = -1;
    }
    void pushdown(int i)
    {
        if(tree[i].lazy != -1)
        {
            if(tree[le(i)].lazy != -1 && tree[i].lazy == 2)
            {
                if(tree[le(i)].lazy == 2)
                    tree[le(i)].lazy = -1;
                else
                    tree[le(i)].lazy ^= 1;
            }
            else
                tree[le(i)].lazy = tree[i].lazy;
    
            if(tree[ri(i)].lazy != -1 && tree[i].lazy == 2)
            {
                if(tree[ri(i)].lazy == 2)
                    tree[ri(i)].lazy = -1;
                else
                    tree[ri(i)].lazy ^= 1;
            }
            else
                tree[ri(i)].lazy = tree[i].lazy;
    
            if(tree[i].lazy == 2)
            {
                if(tree[le(i)].cov != -1)
                    tree[le(i)].cov ^= 1;
                if(tree[ri(i)].cov != -1)
                    tree[ri(i)].cov ^= 1;
            }
            else
                tree[le(i)].cov = tree[ri(i)].cov = tree[i].lazy;
    
            tree[i].lazy = -1;
        }
    }
    void built(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].lazy = -1;
        tree[i].cov = 0;
        if(l == r)
            return;
        int mid = (l + r) >> 1;
        built(le(i),l,mid);
        built(ri(i),mid + 1,r);
    }
    void update(int i,int l,int r,int op)//op:0为置空,1为置满,2为互换
    {
        if(r < l)
            return;
        if(tree[i].l >= l && tree[i].r <= r)
        {
            if(tree[i].lazy != -1 && op == 2)
            {
                if(tree[i].lazy == 2)
                    tree[i].lazy = -1;
                else
                    tree[i].lazy ^= 1;
            }
            else
                tree[i].lazy = op;
            if(op == 2)
            {
                if(tree[i].cov != -1)
                    tree[i].cov ^= 1;
            }
            else
                tree[i].cov = op;
            return;
        }
        if(tree[i].l > r|| tree[i].r < l)
            return;
        pushdown(i);
        update(le(i),l,r,op);
        update(ri(i),l,r,op);
        pushup(i);
    }
    void query(int i)
    {
        if(!tree[i].cov)
            return;
        if(tree[i].cov == 1)
        {
            for(int k = tree[i].l; k <= tree[i].r; k++)
                s[k] = 1;
            return;
        }
        else
        {
            pushdown(i);
            query(le(i));
            query(ri(i));
        }
    }
    int main()
    {
        char c,l0,r0;
        int l,r;
        built(1,0,N);
        while(scanf(" %c %c%d,%d %c",&c,&l0,&l,&r,&r0) != EOF)
        {
            if(l0 == '(')
                l = l<<1|1;
            else
                l <<= 1;
            if(r0 == ')')
                r = (r<<1) - 1;
            else
                r <<= 1;
            if(c == 'U')
                update(1,l,r,1);
            else if(c == 'I')
            {
                update(1,0,l-1,0);
                update(1,r+1,N,0);
            }
            else if(c == 'D')
                update(1,l,r,0);
            else if(c == 'C')
            {
                update(1,0,l-1,0);
                update(1,r+1,N,0);
                update(1,l,r,2);
            }
            else
                update(1,l,r,2);
        }
        query(1);
        int a = -1,flag = 0;
        for(int i = 0; i <= N + 1; i++)
        {
            if(s[i] && a == -1)
                a = i,flag = 1;
            if(!s[i] && a != -1)
            {
                if(a&1)
                    printf("(%d,",a>>1);
                else
                    printf("[%d,",a>>1);
                if(i&1)
                    printf("%d] ",i>>1);
                else
                    printf("%d) ",i>>1);
                a = -1;
            }
        }
        if(!flag)
            printf("empty set");
        printf("
    ");
        return 0;
    }
    

      

    ③POJ5023

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023

    由于颜色只有30种,所以可以用位存储,网上看到的好神奇,我却只能想到set

    #include<bits/stdc++.h>
    #define le i<<1
    #define ri i<<1|1
    using namespace std;
    const int N = 1e6 + 5;
    int ans;
    struct node
    {
        int l,r,lazy,color;
    }tree[N<<2];
    void pushup(int i)
    {
        tree[i].color = tree[le].color | tree[ri].color;
    }
    void pushdown(int i)
    {
        if(tree[i].lazy)
        {
            tree[le].lazy = tree[ri].lazy = tree[i].lazy;
            tree[le].color = tree[ri].color = 1<<tree[i].lazy;
            tree[i].lazy = 0;
        }
    }
    void built(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].lazy = 0;
        tree[i].color = 4;
        if(l == r)
            return;
        int mid = (l + r) >> 1;
        built(le,l,mid);
        built(ri,mid + 1,r);
    }
    void update(int i,int l,int r,int c)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            tree[i].lazy = c;
            tree[i].color = 1<<c;
            return;
        }
        if(tree[i].l > r || tree[i].r < l)
            return;
        pushdown(i);
        update(le,l,r,c);
        update(ri,l,r,c);
        pushup(i);
    }
    void query(int i,int l,int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            ans |= tree[i].color;
            return;
        }
        if(tree[i].l > r || tree[i].r < l)
            return;
        pushdown(i);
        query(le,l,r);
        query(ri,l,r);
    }
    int main()
    {
        int n,m,c,l,r;
        char com;
        while(scanf("%d %d",&n,&m))
        {
            if(!n && !m)
                break;
            built(1,1,n);
            while(m--)
            {
                scanf(" %c",&com);
                if(com == 'P')
                {
                    scanf("%d %d %d",&l,&r,&c);
                    update(1,l,r,c);
                }
                else
                {
                    scanf("%d %d",&l,&r);
                    query(1,l,r);
                    int flag = 0;
                    for(int i = 1; i <= 30; i++)
                    {
                        ans >>= 1;
                        if(ans & 1)
                        {
                            if(!flag)
                                printf("%d",i), flag = 1;
                            else
                                printf(" %d",i);
                        }
                    }
                    puts("");
                }
                ans = 0;
            }
        }
        return 0;
    }
    

      

    ④HDU4578

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578

    思路:对于操作1、2,设k为增加倍数,b为增加数量,初始状态k = 1,b = 0

    有递推公式sum1 = ∑(kx + b) = k*sum1 + b*len

         sum2 = ∑(kx + b)² = ∑(k²x² + 2kxb + b²) = k² * sum2 + 2*k*sum1*b + b² * len

                     sum3 = ∑(kx + b)³ = ∑(k³x³ + 3k²x²b + 3kxb² + b³) = k³ * sum3 + 3 * k² * sum2 * b + 3 * k * sum1 * b² + b³ * len

    对于操作3,会覆盖之前的操作,之前的操作应清零

    该死的宏定义

    #include<bits/stdc++.h>
    #define N 100005
    #define M 10007
    #define le i<<1
    #define ri i<<1|1
    using namespace std;
    struct node
    {
        int l,r,lazy1,lazy2,lazy3,sum1,sum2,sum3;
        int len()
        {
            return (r - l + 1) % M;
        }
    }tree[N<<2];
    void add_mul(int i,int k,int b)
    {
        int s1 = tree[i].sum1 % M;
        int s2 = tree[i].sum2 % M;
        int s3 = tree[i].sum3 % M;
        int len = tree[i].len() % M;
        tree[i].lazy1 = (k % M * tree[i].lazy1 % M + b % M) % M;
        tree[i].lazy2 = k % M * tree[i].lazy2 % M;
        tree[i].sum1 = (k % M * s1 % M + b % M * len % M) % M;
        tree[i].sum2 = (k % M * k % M * s2 % M + 2 * k % M * s1 % M * b % M + b % M * b % M * len % M) % M;
        tree[i].sum3 = (k % M * k % M * k % M * s3 % M + 3 * k % M * k % M * s2 % M * b % M + 3 * k % M * s1 % M * b % M * b % M + b % M * b % M * b % M * len % M) % M;
    }
    void equ(int i,int c)
    {
        tree[i].lazy1 = 0;
        tree[i].lazy2 = 1;
        tree[i].lazy3 = c;
        tree[i].sum1 = c * tree[i].len() % M;
        tree[i].sum2 = c * c % M * tree[i].len() % M;
        tree[i].sum3 = c * c % M * c % M * tree[i].len() % M;
    }
    void pushup(int i)
    {
        tree[i].sum1 = (tree[le].sum1 + tree[ri].sum1) % M;
        tree[i].sum2 = (tree[le].sum2 + tree[ri].sum2) % M;
        tree[i].sum3 = (tree[le].sum3 + tree[ri].sum3) % M;
    }
    void pushdown(int i)
    {
        if(tree[i].lazy3)
        {
            equ(le,tree[i].lazy3);
            equ(ri,tree[i].lazy3);
            tree[i].lazy3 = 0;
        }
        if(tree[i].lazy1 != 0 || tree[i].lazy2 != 1)
        {
            add_mul(le,tree[i].lazy2,tree[i].lazy1);
            add_mul(ri,tree[i].lazy2,tree[i].lazy1);
            tree[i].lazy1 = 0;
            tree[i].lazy2 = 1;
        }
    }
    void built(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].lazy1 = 0;
        tree[i].lazy2 = 1;
        tree[i].lazy3 = 0;
        tree[i].sum1 = tree[i].sum2 = tree[i].sum3 = 0;
        if(l == r)
            return;
        int mid = (l + r) >> 1;
        built(le,l,mid);
        built(ri,mid + 1,r);
    }
    void update(int i,int l,int r,int op,int c)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            if(op == 1)
                add_mul(i,1,c);
            else if(op == 2)
                add_mul(i,c,0);
            else
                equ(i,c);
            return;
        }
        if(tree[i].l > r || tree[i].r < l)
            return;
        pushdown(i);
        update(le,l,r,op,c);
        update(ri,l,r,op,c);
        pushup(i);
    }
    int query(int i,int l,int r,int c)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            if(c == 1)
                return tree[i].sum1 % M;
            if(c == 2)
                return tree[i].sum2 % M;
            if(c == 3)
                return tree[i].sum3 % M;
        }
        if(tree[i].l > r || tree[i].r < l)
            return 0;
        pushdown(i);
        return (query(le,l,r,c) + query(ri,l,r,c)) % M;
    }
    int main()
    {
        int n,m;
        while(scanf("%d %d",&n,&m))
        {
            if(n == 0 && m == 0)
                break;
            built(1,1,n);
            while(m--)
            {
                int op,x,y,c;
                scanf("%d %d %d %d",&op,&x,&y,&c);
                if(op == 4)
                    printf("%d
    ",query(1,x,y,c) % M);
                else
                    update(1,x,y,op,c);
            }
        }
        return 0;
    }
    

      

     ⑥HDU3397

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397

    #include<bits/stdc++.h>
    #define lson i<<1
    #define rson i<<1|1
    using namespace std;
    const int N = 1e5 + 5;
    int str[N];
    struct node
    {
        int l,r;
        int lazy;
        int num1;
        int ls1,rs1,ms1;
        int ls0,rs0,ms0;
        int len()
        {
            return r - l + 1;
        }
    }tree[N<<2];
    void change(int i,int op)
    {
        if(op == 2)
        {
            swap(tree[i].ls0,tree[i].ls1);
            swap(tree[i].rs0,tree[i].rs1);
            swap(tree[i].ms0,tree[i].ms1);
            tree[i].lazy = 1 - tree[i].lazy;
            tree[i].num1 = tree[i].len() - tree[i].num1;
        }
        else if(op == 1)
        {
            tree[i].lazy = 1;
            tree[i].ls1 = tree[i].rs1 = tree[i].ms1 = tree[i].num1 = tree[i].len();
            tree[i].ls0 = tree[i].rs0 = tree[i].ms0 = 0;
        }
        else
        {
            tree[i].lazy = 0;
            tree[i].ls0 = tree[i].rs0 = tree[i].ms0 = tree[i].len();
            tree[i].ls1 = tree[i].rs1 = tree[i].ms1 = tree[i].num1 = 0;
        }
    }
    void pushup(int i)
    {
        if(tree[lson].ls1 == tree[lson].len())
            tree[i].ls1 = tree[lson].ls1 + tree[rson].ls1;
        else
            tree[i].ls1 = tree[lson].ls1;
        if(tree[rson].rs1 == tree[rson].len())
            tree[i].rs1 = tree[rson].rs1 + tree[lson].rs1;
        else
            tree[i].rs1 = tree[rson].rs1;
    
        if(tree[lson].ls0 == tree[lson].len())
            tree[i].ls0 = tree[lson].ls0 + tree[rson].ls0;
        else
            tree[i].ls0 = tree[lson].ls0;
        if(tree[rson].rs0 == tree[rson].len())
            tree[i].rs0 = tree[rson].rs0 + tree[lson].rs0;
        else
            tree[i].rs0 = tree[rson].rs0;
        tree[i].ms1 = max(max(tree[lson].ms1,tree[rson].ms1),tree[lson].rs1 + tree[rson].ls1);
        tree[i].ms0 = max(max(tree[lson].ms0,tree[rson].ms0),tree[lson].rs0 + tree[rson].ls0);
        tree[i].num1 = tree[lson].num1 + tree[rson].num1;
    }
    void pushdown(int i)
    {
        if(tree[i].lazy != -1)
        {
            change(lson,tree[i].lazy);
            change(rson,tree[i].lazy);
            tree[i].lazy = -1;
        }
    }
    void built(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].lazy = -1;
        if(l == r)
        {
            tree[i].num1 = str[l];
            tree[i].ls1 = tree[i].rs1 = tree[i].ms1 = str[l];
            tree[i].ls0 = tree[i].rs0 = tree[i].ms0 = str[l]^1;
            return;
        }
        int mid = (l + r) >> 1;
        built(lson,l,mid);
        built(rson,mid+1,r);
        pushup(i);
    }
    void update(int i,int l,int r,int op)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            change(i,op);
            return;
        }
        if(tree[i].l > r || tree[i].r < l)
            return;
        pushdown(i);
        update(lson,l,r,op);
        update(rson,l,r,op);
        pushup(i);
    }
    int query(int i,int l,int r,int op)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            if(op == 3)
                return tree[i].num1;
            else
                return tree[i].ms1;
        }
        if(tree[i].l > r || tree[i].r < l)
            return 0;
        pushdown(i);
        if(op == 3)
            return query(lson,l,r,op) + query(rson,l,r,op);
        else
        {
            int res1 = min(tree[lson].rs1,tree[lson].r - l + 1) + min(tree[rson].ls1,r - tree[rson].l + 1);
            int res2 = max(query(lson,l,r,op),query(rson,l,r,op));
            return max(res1,res2);
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m;
            scanf("%d %d",&n,&m);
            for(int i = 0; i < n; i++)
                scanf("%d",str+i);
            built(1,0,n-1);
            while(m--)
            {
                int op,a,b;
                scanf("%d %d %d",&op,&a,&b);
                if(op <= 2)
                    update(1,a,b,op);
                else
                    printf("%d
    ",query(1,a,b,op));
            }
        }
        return 0;
    }
    

      

    ⑦HDU3016(DAG最长路DP + 线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3016

    题意:本来看错了,以为板上都可以跳。其实只能在板的两端垂直下落。

    //不得不承认专项练习还是有个弊端,就是知道它归类于线段树就会拼命往线段树想,要是直接上手的话我肯定想不到。

    思路:downl,downr分别表示从该板左右两端跳会落到哪块板子上(id),这样就可以利用线段树建立出一个DAG。然后就是经典的最长路DP。

    #include<bits/stdc++.h>
    #define lson i<<1
    #define rson i<<1|1
    using namespace std;
    const int N = 1e5 + 5;
    const int inf = 0x3f3f3f3f;
    int dp[N];
    struct Board
    {
        int l,r;
        int h,val;
        int downl,downr;
        bool operator < (Board t)
        {
            return h < t.h;
        }
    }board[N];
    struct node
    {
        int l,r;
        int cov;
    }tree[N<<2];
    void pushup(int i)
    {
        if(tree[lson].cov == tree[rson].cov)
            tree[i].cov = tree[lson].cov;
        else
            tree[i].cov = -1;
    }
    void pushdown(int i)
    {
        if(tree[i].cov != -1)
        {
            tree[lson].cov = tree[rson].cov = tree[i].cov;
            tree[i].cov = -1;
        }
    }
    void built(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].cov = 0;
        if(l == r)
            return;
        int mid = (l + r) >> 1;
        built(lson,l,mid);
        built(rson,mid+1,r);
    }
    void update(int i,int l,int r,int id)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            tree[i].cov = id;
            return;
        }
        if(tree[i].l > r || tree[i].r < l)
            return;
        pushdown(i);
        update(lson,l,r,id);
        update(rson,l,r,id);
        pushup(i);
    }
    int query(int i,int c)
    {
        if(tree[i].cov != -1)
            return tree[i].cov;
        int mid = (tree[i].l + tree[i].r) >> 1;
        if(c <= mid)
            return query(lson,c);
        else
            return query(rson,c);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            for(int i = 1; i <= n; i++)
                scanf("%d %d %d %d",&board[i].h,&board[i].l,&board[i].r,&board[i].val);
            sort(board + 1,board + n + 1);
            built(1,1,100000);
            for(int i = 1; i <= n; i++)
            {
                board[i].downl = query(1,board[i].l);
                board[i].downr = query(1,board[i].r);
                update(1,board[i].l,board[i].r,i);
            }
            memset(dp,-inf,sizeof(dp));
            dp[n] = 100 + board[n].val;
            for(int i = n; i >= 1; i--)
            {
                if(dp[i] < 0)
                    dp[i] = -inf;
                dp[board[i].downl] = max(dp[board[i].downl], dp[i] + board[board[i].downl].val);
                dp[board[i].downr] = max(dp[board[i].downr], dp[i] + board[board[i].downr].val);
            }
            if(dp[0] <= 0)
                puts("-1");
            else
                printf("%d
    ",dp[0]);
        }
        return 0;
    }
    

      

    ⑧POJ3577

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577

    #include<bits/stdc++.h>
    #define lson i<<1
    #define rson i<<1|1
    using namespace std;
    const int N = 1e6 + 5;
    bool yes[100005];
    struct node
    {
        int l,r;
        int lazy,maxm;
    }tree[N<<2];
    void pushdown(int i)
    {
        if(tree[i].lazy)
        {
            tree[lson].lazy += tree[i].lazy;
            tree[rson].lazy += tree[i].lazy;
            tree[lson].maxm += tree[i].lazy;
            tree[rson].maxm += tree[i].lazy;
            tree[i].lazy = 0;
        }
    }
    void built(int i,int l,int r)
    {
        tree[i].l = l;
        tree[i].r = r;
        tree[i].lazy = tree[i].maxm = 0;
        if(l == r)
            return;
        int mid = (l + r) >> 1;
        built(lson,l,mid);
        built(rson,mid+1,r);
    }
    void update(int i,int l,int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            tree[i].lazy++;
            tree[i].maxm++;
            return;
        }
        if(tree[i].l > r || tree[i].r < l)
            return;
        pushdown(i);
        update(lson,l,r);
        update(rson,l,r);
        tree[i].maxm = max(tree[lson].maxm,tree[rson].maxm);
    }
    int query(int i,int l,int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
            return tree[i].maxm;
        if(tree[i].l > r || tree[i].r < l)
            return 0;
        pushdown(i);
        return max(query(lson,l,r),query(rson,l,r));
    }
    int main()
    {
        int T,cas = 1,k,Q,a,b;
        scanf("%d",&T);
        while(T--)
        {
            memset(yes,0,sizeof(yes));
            scanf("%d %d",&k,&Q);
            built(1,1,1000000);
            for(int i = 1; i <= Q; i++)
            {
                scanf("%d %d",&a,&b);
                if(query(1,a,b-1) < k)
                {
                    yes[i] = 1;
                    update(1,a,b-1);
                }
            }
            printf("Case %d:
    ",cas++);
            for(int i = 1; i <= Q; i++)
            {
                if(yes[i])
                    printf("%d ",i);
            }
            printf("
    
    ");
        }
        return 0;
    }
    

    ⑨HDU5316(单点更新,区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316

    题意:给出一个长度为n的序列,有两种操作,op = 0时求出区间[a,b]中奇偶相间(不含空)的子序列的和的最大值,op = 1时把a改成b

    思路:oo表示该节点区间[L,R]上以奇开头奇结尾的子序列的和的最大值,oe,eo,ee同理......

    自己之前的查询部分写的有点赘,TLE了,网上看了别人的写了下,发现之前的几题也可以简化下代码量的。

    #include<bits/stdc++.h>
    #define lson i<<1
    #define rson i<<1|1
    using namespace std;
    typedef long long ll;
    const int N = 1e5 + 5;
    const ll inf = 1e18;
    ll MAX(ll a,ll b,ll c,ll d)
    {
        return max(max(a,b),max(c,d));
    }
    struct node
    {
        ll oo,oe,eo,ee;
        node() {}
        node(ll oo,ll oe,ll eo, ll ee):oo(oo),oe(oe),eo(eo),ee(ee) {}
    }tree[N<<2];
    node pushup(node a,node b)
    {
        node res;
        res.oo = MAX(a.oo, b.oo, a.oo + b.eo, a.oe + b.oo);
        res.oe = MAX(a.oe, b.oe, a.oo + b.ee, a.oe + b.oe);
        res.eo = MAX(a.eo, b.eo, a.eo + b.eo, a.ee + b.oo);
        res.ee = MAX(a.ee, b.ee, a.eo + b.ee, a.ee + b.oe);
        return res;
    }
    void built(int i,int L,int R)
    {
        if(L == R)
        {
            if(L & 1)
                scanf("%lld",&tree[i].oo), tree[i].oe = tree[i].eo = tree[i].ee = -inf;
            else
                scanf("%lld",&tree[i].ee), tree[i].oo = tree[i].oe = tree[i].eo = -inf;
            return;
        }
        int mid = (L + R) >> 1;
        built(lson,L,mid);
        built(rson,mid+1,R);
        tree[i] = pushup(tree[lson],tree[rson]);
    }
    void update(int i,int L,int R,int pos,ll val)
    {
        if(L == R)
        {
            if(L & 1)
                tree[i].oo = val;
            else
                tree[i].ee = val;
            return;
        }
        int mid = (L + R) >> 1;
        if(pos <= mid)
            update(lson,L,mid,pos,val);
        else
            update(rson,mid+1,R,pos,val);
        tree[i] = pushup(tree[lson],tree[rson]);
    }
    node query(int i,int L,int R,int l,int r)
    {
        if(L >= l && R <= r)
            return tree[i];
        if(L > r || R < l)
            return node(-inf,-inf,-inf,-inf);
        int mid = (L + R) >> 1;
        return pushup(query(lson,L,mid,l,r),query(rson,mid+1,R,l,r));
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m;
            scanf("%d %d",&n,&m);
            built(1,1,n);
            while(m--)
            {
                int op,a,b;
                scanf("%d %d %d",&op,&a,&b);
                if(op)
                    update(1,1,n,a,b);
                else
                {
                    node ans = query(1,1,n,a,b);
                    printf("%lld
    ",MAX(ans.oo,ans.oe,ans.eo,ans.ee));
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    webServer xampp的安装及使用
    javascript 原生方法监听DOM结构改变事件
    c# 文件简繁体转换
    c# 网络是否连接
    JMS
    JMS
    JMS
    Quartz Scheduler(2.2.1)
    MySQL
    Git CMD
  • 原文地址:https://www.cnblogs.com/westwind1005/p/7100732.html
Copyright © 2011-2022 走看看