Luogu P2184 贪婪大陆
Posted huangchenyan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",tot-s[l-1][1]-s[r+1][2]);//答案
以上是关于Luogu P2184 贪婪大陆的主要内容,如果未能解决你的问题,请参考以下文章