码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu P2184 贪婪大陆

时间:2019-08-04 10:32:53      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:多少   总数   ace   维护   相交   turn   可以转化   注意   namespace   

线段树

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

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

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

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

(我没想到)

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

即$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\n",tot-s[l-1][1]-s[r+1][2]);//答案
        }
    }
}

 

Luogu P2184 贪婪大陆

标签:多少   总数   ace   维护   相交   turn   可以转化   注意   namespace   

原文地址:https://www.cnblogs.com/huangchenyan/p/11297356.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!