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

    1. 1077 : RMQ问题再临-线段树

    http://hihocoder.com/problemset/problem/1077

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    #define N 10005
    #define min(a,b) (a<b?a:b)
    int n;
    
    struct node
    {
        int l, r;
        int min;
    }node[N << 2];
    
    int BuildTree(int l, int r, int k)
    {
    //    printf("%d %d %d
    ", l, r, k);
        node[k].l = l;
        node[k].r = r;
        if (l == r)
        {
            scanf("%d", &node[k].min);
            return 0;
        }
        BuildTree(l, (l + r) / 2, k * 2);
        BuildTree((l + r) / 2 + 1, r, k * 2 + 1);
        node[k].min = min(node[k * 2].min, node[k * 2 + 1].min);
        return 0;
    }
    
    int Query(int l, int r, int k)
    {
        if (l <= node[k].l && r >= node[k].r)
            return node[k].min;
        int minl = N, minr = N;
        if (l <= node[k * 2].r)
            minl = Query(l, r, k * 2);
        if (r >= node[k * 2 + 1].l)
            minr = Query(l, r, k * 2 + 1);
        return min(minl,minr);
    }
    
    int Change(int p, int w, int k)
    {
        if (node[k].l == node[k].r)
        {
            node[k].min = w;
            return 0;
        }
        if (p <= node[k * 2].r)
            Change(p, w, k * 2);
        if (p >= node[k * 2 + 1].l)
            Change(p, w, k * 2 + 1);
        node[k].min = min(node[k * 2].min, node[k * 2 + 1].min);
        return 0;
    }
    
    int main()
    {
        int q, k, a, b, i;
        scanf("%d", &n);
        BuildTree(1,n,1);
        scanf("%d", &q);
        for (i = 1; i <= q; i++)
        {
            scanf("%d%d%d", &k, &a, &b);
            k ? Change(a, b, 1) : printf("%d
    ",Query(a, b, 1));
        }
    
        return 0;
    }

    2. #1078 : 线段树的区间修改(LazyTag)

    http://hihocoder.com/problemset/problem/1078

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #define N 100005
    
    struct node
    {
        int l, r;
        int len;
        int sum;
        int lazytag; //为0时表示没有lazytag,非0时表示要修改的单价
    }node[N<<2];
    
    void BuildTree(int l, int r, int k)
    {
        node[k].l = l;
        node[k].r = r;
        node[k].len = r - l + 1;
        node[k].lazytag = 0;
        if (l == r)
        {
            scanf("%d", &node[k].sum);
            return;
        }
        BuildTree(l, (l + r) / 2, k * 2);
        BuildTree((l + r) / 2 + 1, r, k * 2 + 1);
        node[k].sum = node[k * 2].sum + node[k * 2 + 1].sum;
    }
    
    int Query(int l, int r, int k)
    {
        if (node[k].l >= l && node[k].r <= r)
            return node[k].sum;
        if (node[k].lazytag)
        {
            node[k * 2].lazytag = node[k].lazytag;
            node[k * 2].sum = node[k].lazytag * node[k * 2].len;
            node[k * 2 + 1].lazytag = node[k].lazytag;
            node[k * 2 + 1].sum = node[k].sum - node[k * 2].sum;
            node[k].lazytag = 0;
        }
        int mid = (node[k].l+node[k].r)/2, lsum = 0, rsum = 0;
        if (l <= mid)
            lsum = Query(l, r, k * 2);
        if (r > mid)
            rsum = Query(l, r, k * 2 + 1);
        return lsum + rsum;
    }
    
    void Change(int l, int r, int p, int k)
    {
    //    printf("%d %d %d %d %d
    ", l, r, k,node[k].l,node[k].r);
        if (l == node[k].l && r == node[k].r)
        {
            node[k].lazytag = p;
            node[k].sum = p * node[k].len;
            return;
        }
        if (node[k].lazytag)
        {
            node[k * 2].lazytag = node[k].lazytag;
            node[k * 2].sum = node[k].lazytag * node[k * 2].len;
            node[k * 2 + 1].lazytag = node[k].lazytag;
            node[k * 2 + 1].sum = node[k].sum - node[k * 2].sum;
            node[k].lazytag = 0;
        }
        int mid = (node[k].l + node[k].r) / 2;
        if (l <= mid)
            Change(l, r<mid?r:mid, p, k * 2);
        if (r > mid)
            Change(l>(mid+1)?l:(mid+1), r, p, k * 2 + 1);
        node[k].sum = node[k * 2].sum + node[k * 2 + 1].sum;
    }
    
    void printTree()
    {
        printf("**********
    ");
        for (int i = 1; i <= 25; i++)
        {
            printf("(%d,%d) %d	", node[i].l, node[i].r, node[i].sum);
        }
        printf("**********
    ");
    }
    
    int main()
    {
        int n, q, k, l, r, p, i;
        scanf("%d", &n);
        BuildTree(1, n, 1);
        printTree();
        scanf("%d", &q);
        for (i = 0; i < q; i++)
        {
            scanf("%d%d%d", &k, &l, &r);
            if (0 == k)
                printf("%d
    ", Query(l, r, 1));
            else
            {
                scanf("%d", &p);
                Change(l, r, p, 1);
            }
    //        printTree();
        }
        return 0;
    }

    3. #1080 : 更为复杂的买卖房屋姿势(两种LazyTag)

    http://hihocoder.com/problemset/problem/1080

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #define N 100005
    
    struct node
    {
        int l, r;
        int len;
        int sum;
        int lazyTagAdd, lazyTagSet;
    }node[N<<2];
    
    void BuildTree(int l, int r, int k)
    {
        node[k].l = l;
        node[k].r = r;
        node[k].len = r - l + 1;
        node[k].lazyTagAdd = 0;
        node[k].lazyTagSet = 0;
        if (l == r)
        {
            scanf("%d", &node[k].sum);
            return;
        }
        int mid = (l + r) >> 1;
        BuildTree(l, mid, k << 1);
        BuildTree(mid + 1, r, (k << 1) | 1);
        node[k].sum = node[k << 1].sum + node[k << 1 | 1].sum;
    }
    
    void Change(int op, int l, int r, int v, int k)
    {
    //    printf("%d %d %d %d %d
    ", op, l, r, v, k);
        if (node[k].len > 1)
        {
            if (node[k].lazyTagSet)
            {
                node[k << 1].lazyTagSet = node[k].lazyTagSet;
                node[k << 1].sum = node[k].lazyTagSet * node[k << 1].len;
                node[k << 1].lazyTagAdd = 0;
                node[k << 1 | 1].lazyTagSet = node[k].lazyTagSet;
                node[k << 1 | 1].sum = node[k].lazyTagSet * node[k << 1 | 1].len;
                node[k << 1 | 1].lazyTagAdd = 0;
                node[k].lazyTagSet = 0;
            }
            if (node[k].lazyTagAdd)
            {
                node[k << 1].lazyTagAdd += node[k].lazyTagAdd;
                node[k << 1].sum += node[k].lazyTagAdd * node[k << 1].len;
                node[k << 1 | 1].lazyTagAdd += node[k].lazyTagAdd;
                node[k << 1 | 1].sum += node[k].lazyTagAdd * node[k << 1 | 1].len;
                node[k].lazyTagAdd = 0;
            }
        }
        if (l <= node[k].l && r >= node[k].r)
        {
            if (0 == op)  //add
            {
                node[k].lazyTagAdd = v;
                node[k].sum += v* node[k].len;
            }
            else
            {
                node[k].lazyTagSet = v;
                node[k].sum = v * node[k].len;
            }
            return;
        }
        int mid = (node[k].l + node[k].r) >> 1;
        if (l <= mid)
            Change(op, l, r, v, k << 1);
        if (r > mid)
            Change(op, l, r, v, k << 1 | 1);
        node[k].sum = node[k << 1].sum + node[k << 1 | 1].sum;
    }
    
    void PrintTree()
    {
        printf("
    ******
    ");
        for (int i = 1; i < 30; i++)
        {
            printf("%d: %d,%d %d
    ", i, node[i].l, node[i].r, node[i].sum);
        }
        printf("
    ******
    ");
    }
    
    int main()
    {
        int n, m, op, l, r, v, i;
        scanf("%d%d", &n, &m);
        BuildTree(0, n, 1);
    //    for (i = 1; i < 30; i++)
    //        printf("%d: %d,%d %d
    ", i, node[i].l, node[i].r, node[i].sum);
        PrintTree();
        for (i = 0; i < m; i++)
        {
            scanf("%d%d%d%d", &op, &l, &r, &v);
            Change(op, l, r, v, 1);
            printf("%d
    ", node[1].sum);
            PrintTree();
        }
        return 0;
    }

    4. #1079 : 离散化

    http://hihocoder.com/problemset/problem/1079

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100005
    int s[N], e[N] ,p[N<<2];
    bool visit[N];
    
    typedef struct Poster
    {
        int v;  //区间端点
        int k;  //序号
    }Poster;
    Poster P[N << 1];
    
    bool cmp(Poster a, Poster b)
    {
        return a.v < b.v;
    }
    
    void BuildTree(int k, int l, int r, int num)
    {
        if (s[num] <= l && e[num] >= r)
        {
            p[k] = num;  //结点k存放的是第num张海报
            return;
        }
        if (p[k])
        {
            p[k << 1] = p[k];
            p[k << 1 | 1] = p[k];
            p[k] = 0;
        }
        int mid = (l + r) / 2;
        if (s[num] < mid)
            BuildTree(k << 1, l, mid, num);
        if (e[num] > mid)
            BuildTree(k << 1 | 1, mid, r, num);
    }
    
    void Check(int k, int l, int r)
    {
        if (l + 1 == r)
        {
            visit[p[k]] = true;
            return;
        }
        if (p[k])
        {
            p[k << 1] = p[k];
            p[k << 1 | 1] = p[k];
            p[k] = 0;
        }
        int mid = (l + r) / 2;
        Check(k << 1, l, mid);
        Check(k << 1 | 1, mid, r);
    }
    
    int main()
    {
        int n, l, i, j;
        cin >> n >> l;
        for (i = 1; i <= n; i++)
        {
            cin >> P[(i << 1) - 1].v;
            P[(i<<1)-1].k = i;
            cin >> P[i << 1].v;
            P[i<<1].k = i + n;
        }
        sort(P + 1, P + (n << 1) + 1, cmp);
        P[(n << 1) + 1].v = -1;
        for (i = 1, j = 1; i <= (n << 1); i++)
        {
            if (P[i].k <= n)
                s[P[i].k] = j;
            else
                e[P[i].k - n] = j;
            if (P[i].v != P[i + 1].v)
                j++;
        }
        memset(p, 0, sizeof(p));
        for (i = 1; i <= n; i++)
            BuildTree(1, 1, j, i);
        memset(visit, 0, sizeof(visit));
        Check(1, 1, j);
        for (i = 1, j = 0; i <= n; i++)
        {
            if (visit[i])
                j++;
        }
        cout << j << endl;
        return 0;
    }

    5. 1116 : 计算

    http://hihocoder.com/problemset/problem/1116?sid=769706

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    const int MOD = 10007;
    const int N = 100005;
    
    typedef struct interval
    {
        //int left, right;
        int sum;
        int pre; //区间内以left为前缀的所有乘积的总和
        int suf; //suffix, 区间内以right为后缀的所有乘积的总和
        int prd; //product, 区间内所有数的乘积,为求父节点的pre
    }interval;
    interval in[N << 1];
    
    void Update(int k)
    {
        while (k)
        {
            in[k].pre = (in[k << 1].pre + in[k << 1].prd * in[k << 1 | 1].pre) % MOD;
            in[k].suf = (in[k << 1].suf * in[k << 1 | 1].prd + in[k << 1 | 1].suf) % MOD;
            in[k].prd = (in[k << 1].prd * in[k << 1 | 1].prd) % MOD;
            in[k].sum = (in[k << 1].sum + in[k << 1 | 1].sum + in[k << 1].suf * in[k << 1 | 1].pre) % MOD;
            k = k >> 1;
        }
    }
    
    void Change(int k, int left, int right, int i, int x)
    {
        if (left == right)
        {
            in[k].sum = x % MOD;
            in[k].pre = x % MOD;
            in[k].suf = x % MOD;
            in[k].prd = x % MOD;
            Update(k >> 1);
            return;
        }
        int mid = (left + right) / 2;
        if (i <= mid)
            Change(k << 1, left, mid, i, x);
        else
            Change(k << 1 | 1, mid + 1, right, i, x);
    }
    
    int main()
    {
        int n, q, x, i;
        scanf("%d%d", &n, &q);
        memset(in, 0, sizeof(in));
        while (q--)
        {
            scanf("%d%d", &i, &x);
            Change(1, 1, n, i, x);
            printf("%d
    ", in[1].sum);
        }
        return 0;
    }
  • 相关阅读:
    智课雅思词汇---十八、前缀peri是什么意思
    新东方雅思词汇---7.1、probation
    智课雅思词汇---十七、前綴il-, in-, ir-, im-有什麼關係
    英语发音规则---U字母-[复习中]
    英语发音规则---O字母
    Android之Http沟通——4.Android HTTP索取信息:HttpClient
    一步一步的理解C++STL迭代器
    Java学习之路:ArrayList用法
    LeetCode:Remove Duplicates from Sorted Array
    【Struts2学习笔记(2)】Action默认值和配置Action于result各种转发类型
  • 原文地址:https://www.cnblogs.com/argenbarbie/p/5383181.html
Copyright © 2011-2022 走看看