bzoj 4237: Divide and Conquer scarecrow cdq

  

 

 

 

How many points for seeking a point which is a point inside the lower left corner of the lower right corner of the rectangle formed by each of x and y is no point is different

 

Start thinking:

First performed in accordance with the x-coordinate cdq divide and conquer sorting  

Then y in the sort cdq enumeration mid + 1-r of the upper right corner point as

Maintenance found a monotonically increasing as long as the left half of the points can be formed with a monotonous stack well maintained

But it ignores the impact of the right half has traversed point answers generated

 

Reference yyb giant guy: https://www.cnblogs.com/cjyyb/p/8419102.ht

 

 Think about the new left point x can be found to affect relations

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
/////////////////////////////////////
const int N=1e6+10;
//维护单调递减的单调栈
int n,m;ll ans[N];ll sum;
struct node{int x,y,id;}s[N];
bool cmp(node a,node b){return a.y>b.y;}
bool cmpx(node a,node b){return a.x<b.x;}
int sta1[N],top1,sta2[N],top2;

void cdq(int l,int r)
{
    if(l==r)return ;int mid=(l+r)>>1;
    cdq(l,mid);cdq(mid+1,r);
    int j=mid+1;
    sort(s+l,s+mid+1,cmp);sort(s+mid+1,s+r+1,cmp);
    int top1=top2=0;
    rep(i,l,mid)
    {
        while(j<=r&&s[i].y<s[j].y)
        {
            while(top1>0&&s[sta1[top1]].x>s[j].x)top1--;
            sta1[++top1]=j++;
        }
        while(top2>0&&s[sta2[top2]].x<s[i].x)top2--;
        sta2[++top2]=i;
        if(top2==1)sum+=1ll*top1;
        else 
        {
            int L=1,R=top1,an=top1+1;
            while(L<=R)
            {
                int mid=(L+R)>>1;
                if(s[sta1[mid]].y>s[sta2[top2-1]].y)L=mid+1;
                else an=mid,R=mid-1;
            }
            sum+=1ll*top1-an+1;
        }
    }
}
int main()
{
    cin>>n;
    rep(i,1,n)
    {
        scanf("%d%d",&s[i].x,&s[i].y);s[i].id=i;
    }
    sort(s+1,s+1+n,cmpx);
    cdq(1,n);
    cout<<sum;
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11469329.html