[BZOJ]4237: 稻草人
题解: 这题很容易绕绕绕
我们考虑分治一下 按x坐标排序 然后对于每一段的两部分都按y排序 左右两边都维护一个单调栈(这个地方栈的顺序要想清楚 不然就会和我一样自闭一小时) 然后考虑右边对左边的贡献就行了
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=3e5+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } typedef struct node{ int x,y; friend bool operator<(node aa,node bb){return aa.x<bb.x;} }node; node d[MAXN]; ll ans; bool cmp(node aa,node bb){return aa.x<bb.x;} bool cmp1(node aa,node bb){return aa.y>bb.y;} int st1[MAXN],st2[MAXN],tot1,tot2; void cdq(int l,int r){ if(l>=r)return ; int mid=(l+r)>>1; sort(d+l,d+mid+1,cmp1); sort(d+mid+1,d+r+1,cmp1); int tot=mid+1;tot1=tot2=0; for(int i=l;i<=mid;i++){ while(tot1&&d[st1[tot1]].x<d[i].x)tot1--; st1[++tot1]=i; while(tot<=r&&d[tot].y>=d[i].y){ while(tot2&&d[st2[tot2]].x>d[tot].x)tot2--; st2[++tot2]=tot; tot++; } if(tot1==1){ans+=tot2;continue;} int t=d[st1[tot1-1]].y; int lx=1;int rx=tot2;int ans1=0; while(lx<=rx){ int midx=(lx+rx)>>1; if(d[st2[midx]].y<=t)ans1=midx,rx=midx-1; else lx=midx+1; } if(ans1&&ans1<=tot2)ans+=(tot2-ans1+1); } sort(d+l,d+r+1,cmp); cdq(l,mid); cdq(mid+1,r); } int main(){ int n=read(); inc(i,1,n)d[i].x=read(),d[i].y=read(); sort(d+1,d+n+1); ans=0; cdq(1,n); printf("%lld\n",ans); }
4237: 稻草人
Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1781 Solved: 788
[Submit][Status][Discuss]
Description
JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典。
有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地。和启示中的一样,田地需要满足以下条件:
田地的形状是边平行于坐标轴的长方形;
左下角和右上角各有一个稻草人;
田地的内部(不包括边界)没有稻草人。
给出每个稻草人的坐标,请你求出有多少遵从启示的田地的个数
Input
第一行一个正整数N,代表稻草人的个数
接下来N行,第i行(1<=i<=N)包含2个由空格分隔的整数Xi和Yi,表示第i个稻草人的坐标
Output
输出一行一个正整数,代表遵从启示的田地的个数
Sample Input
4
0 0
2 2
3 4
4 3
0 0
2 2
3 4
4 3
Sample Output
3