BZOJ 4237 稻草人 CDQ分治+单调栈
不是很难想,但是细节巨多
开始一个地方想错了,然后......
code:
#include <bits/stdc++.h> #define N 2000006 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,ans[N]; struct node { int x,y,id; }a[N],tmp[N],S[N],s2[N]; bool cmpx(node a,node b) { return a.x<b.x; } bool cmpy(node a,node b) { return a.y>b.y; } void solve(int l,int r) { if(l>=r) return; int mid=(l+r)>>1,tl=0,sta=0,t2=0; for(int i=l;i<=r;++i) tmp[++tl]=a[i]; sort(tmp+1,tmp+1+tl,cmpy); for(int i=1;i<=tl;++i) { if(tmp[i].x<=a[mid].x) // 左区间 { while(t2&&tmp[i].x>s2[t2].x) --t2; s2[++t2]=tmp[i]; ans[tmp[i].id]+=sta; if(t2>1) { int l=1,r=sta,mid,re=0; while(l<=r) { mid=(l+r)>>1; if(s2[t2-1].y<=S[mid].y) re=mid,l=mid+1; else r=mid-1; } ans[tmp[i].id]-=re; } } else // 右区间 { while(sta&&S[sta].x>tmp[i].x) --sta; S[++sta]=tmp[i]; } } solve(l,mid), solve(mid+1,r); } int main() { // setIO("input"); int i,j; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y), a[i].id=i; sort(a+1,a+1+n,cmpx); solve(1,n); ll re=0; for(i=1;i<=n;++i) re+=(ll)ans[i]; printf("%lld\n",re); return 0; }