• 区间更新+单点查询


    F: 操作数

    题解:和刷气球那题一样,判断每个位置被更新的次数,如果是奇数输出1,偶数输出0

    注意:用cin会超时

    一、线段树

    //注意laz[]要和线段树数组开一样大小
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    const int  N = 100050;
    using namespace std;
    int tre[N * 4];
    void pushdown(int num);
    // void pushdown(int num)
    // {
    //     if (laz[num] != 0)
    //     {
    //         tre[num * 2] += laz[num];
    //         tre[num * 2 + 1] += laz[num];
    //         laz[num * 2] += laz[num];
    //         laz[num * 2 + 1] += laz[num];
    //         laz[num] = 0;
    //     }
    // }
    void update(int num, int le, int ri, int x, int y)
    {
        if (le >= x && ri <= y)
        {
            tre[num]++;
            return;
        }
        int mid = (le + ri) >> 1;
        if (tre[num])
            pushdown(num);
        if (x <= mid)
            update(num << 1, le, mid, x, y);
        if (y > mid)
            update(num << 1 | 1, mid + 1, ri, x, y);
    }
    void pushdown(int num)
    {
        tre[num << 1] += tre[num];
        tre[num << 1 | 1] += tre[num];
        tre[num] = 0;
    }
    int query(int num, int le, int ri, int x)
    {
        if (le == ri)
            return tre[num];
        int ans, mid = (le + ri) >> 1;
        if (tre[num])
            pushdown(num);
        if (x <= mid)
            ans = query(num << 1, le, mid, x);
        else
            ans = query(num << 1 | 1, mid + 1, ri, x);
        return ans;
    }
    int main()
    {
        int t, n, m;
        scanf("%d%d",&n,&m);
        memset(tre, 0, sizeof(tre));
        //memset(laz, 0, sizeof(laz));//初始化延迟标记
        while (m--)
        {
            scanf("%d",&t);
            if (t == 1)
            {
                int x, y;
                scanf("%d%d",&x,&y);
                update(1, 1, n, x, y);
            }
            else
            {
                int x;
                scanf("%d",&x);
                int cnt = query(1, 1, n, x);
                if (cnt % 2 == 0)
                    cout << 0 << endl;
                else
                    cout << 1 << endl;
            }
        }
        return 0;
    }

    二、树状数组

    树状数组区间更新,因为树状数组都是从起点开始一直更新到最后一个位置,所以在更新区间的时候要用到类似前缀和的思想

    将区间[x,y]的值加z(z可正可负)

    1、将区间[x,n]的值加上z

    2、将区间[y,n]的值减上z

    以上两步实现将区间[x,y]的值加上z

    //注意laz[]要和线段树数组开一样大小
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    const int  N = 5000005;
    using namespace std;
    int n,m;
    int c[N];
    int lowbit(int x) 
    {
        return x&-x;
    }
    void update(int x,int p) 
    {
        while (x<=n) 
        {
            c[x]+=p;
            x+=lowbit(x);
        }
    }
    int sum(int x) 
    {
        int ans=0;
        while (x) 
        {
            ans+=c[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int main() 
    {
        scanf("%d%d",&n,&m);
        memset(c,0,sizeof(c));
        while(m--)
        {
            int t,x,y;
            scanf("%d",&t);
            if (t==1) 
            {
                scanf("%d%d",&x,&y);
                update(x,1);
                update(y+1,-1);
            } 
            else 
            {
                scanf("%d",&x);
                if (sum(x)%2==1) 
                    printf("1
    ");
                else 
                    printf("0
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    国债预发行
    解决GDI+的DrawString绘制带有偏移的问题
    大数据量下查询显示优化方案小结
    《提高C++性能的编程技术》 读书笔记
    基金TA系统简介
    关于做对和做好的一点思考
    调试网络断线工作心得
    双目视觉简介
    PCL中outofcore模块---基于核外八叉树的大规模点云的显示
    深度相机Astra Pro测试教程
  • 原文地址:https://www.cnblogs.com/-citywall123/p/11924066.html
Copyright © 2020-2023  润新知