zoukankan      html  css  js  c++  java
  • 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]);//答案
            }
        }
    }
  • 相关阅读:
    为自己的开篇
    软考程序员笔记
    centos php7 安装mysqli扩展心得
    php判断访问协议是否是https
    go语言新建多维map集合
    获取contenteditable区域光标所在位置信息
    ckeditor中 config.js等通过ckeditor.js引入文件手动修改方法
    Vue使用——v-for循环里面使用v-if判断显示数据
    数据库关联字段设置
    Spring Jpa 自动建表——时间字段设置
  • 原文地址:https://www.cnblogs.com/huangchenyan/p/11297356.html
Copyright © 2011-2022 走看看