• Luogu P2184 贪婪大陆


    线段树

    我居然想了一个半小时才想出来

    读完题可以发现如果布不同地雷的区间如果相交的话,地雷是不会覆盖的

    两种不同的地雷会共存在一格中

    那么在问题可以转化,所求答案就是当前询问的区间与之前布地雷的区间有多少个相交或包含

    (我没想到)

    那么考虑一个区间不与另一个区间相交的条件

    即$r_{1}<l_{2}$或$l_{1}>r_{2}$

    那么可以用线段树维护对于每个点区间右端点小于等于这点的区间数量$s1$,和左端点大于等于这点的区间数量$s2$

    那么询问时答案就是当前布地雷的总数量减去$s1[l-1]$和$s2[r+1]$

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=2*1e5+100;
    int n,m,s[MAXN][3],tot;
    struct node
    {
        int l,r,lazy[3];
    }sh[MAXN*4];
    void pushdown(int x)
    {
        for (int i=1;i<=2;i++)
        {
            if (sh[x+x].l==sh[x+x].r)
              s[sh[x+x].l][i]+=sh[x].lazy[i];
            if (sh[x+x+1].l==sh[x+x+1].r)
              s[sh[x+x+1].l][i]+=sh[x].lazy[i];
            sh[x+x].lazy[i]+=sh[x].lazy[i];
            sh[x+x+1].lazy[i]+=sh[x].lazy[i];
            sh[x].lazy[i]=0;
        }
    }
    void build(int x,int ll,int rr)
    {
        sh[x].l=ll;
        sh[x].r=rr;
        if (ll==rr)
          return;
        int mid;
        mid=(ll+rr)>>1;
        build(x+x,ll,mid);
        build(x+x+1,mid+1,rr);
    }
    void change(int x,int ll,int rr,int kind)//区间修改
    {
        if (sh[x].l>=ll && sh[x].r<=rr)
        {
            sh[x].lazy[kind]++;
            if (sh[x].l==sh[x].r)//注意如果当前修改的已经是单个元素,修改信息
              s[sh[x].l][kind]++;
            return;
        }
        pushdown(x);
        int mid;
        mid=(sh[x].l+sh[x].r)>>1;
        if (ll<=mid)
          change(x+x,ll,rr,kind);
        if (rr>mid)
          change(x+x+1,ll,rr,kind);
    }
    void allchange(int x,int wh)//下放懒标记
    {
        pushdown(x);
        if (sh[x].l==sh[x].r)
          return;
        int mid;
        mid=(sh[x].l+sh[x].r)>>1;
        if (wh<=mid)
          allchange(x+x,wh);
        else
          allchange(x+x+1,wh);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for (int i=1;i<=m;i++)
        {
            int q,l,r;
            scanf("%d%d%d",&q,&l,&r);
            if (q==1)
            {
                change(1,r,n,1);
                change(1,1,l,2);
                tot++;
            }
            else
            {
                allchange(1,l-1);
                allchange(1,r+1);
                printf("%d
    ",tot-s[l-1][1]-s[r+1][2]);//答案
            }
        }
    }
  • 相关阅读:
    【一句日历】2020年3月
    写给我们项目总监的一些话
    基于ajax 的 几个例子 session ,ajax 实现登录,验证码 ,实现ajax表单展示
    day 51 随机验证码, 验证登陆 ,以及 装饰器在函数中的应用
    day 51 cooike 与 session
    day 50 AJAX 初入门
    day 38 jq 入门 学习(一)
    转的大佬的 学习方法
    day 49 数据分析, 数据聚合 F 查询 Q 查询
    day 48 ORM 进阶 多表连接 创建 以及 html模板继承
  • 原文地址:https://www.cnblogs.com/huangchenyan/p/11297356.html
Copyright © 2020-2023  润新知