zoukankan      html  css  js  c++  java
  • bzoj 4237: 稻草人 cdq分治

      

    求有多少个点对  其一个点为左下角  一个点为右下角所形成的矩形内部没有点 每个x与y都不同

    一开始的思路:

    先按照x坐标排序  进行cdq分治  

    然后在cdq内对y进行排序  枚举mid+1-r的点作为右上角的点

    发现只要维护左半边的的单调递增就可以形成点对  用单调栈很好的维护

    但是忽略了右半边已经遍历过的点对答案产生的影响

    参考了yyb巨佬:https://www.cnblogs.com/cjyyb/p/8419102.ht

     想一下新增点的x左边可以发现影响关系

    #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
  • 相关阅读:
    公布一些常用的WebServices
    ARM的嵌入式Linux应用程序开发研究
    c++读写剪贴板代码
    如何破解路由器密码(CISCO)!
    用Shell扩展实现源代码统计程序(转)
    图文例解C++类的多重继承与虚拟继承
    MSDN上关于ADO示例代码
    不错的句子
    codeforces #271(div2) F. Ant colony
    [Z]CUDA中Bank conflict冲突
  • 原文地址:https://www.cnblogs.com/bxd123/p/11469329.html
Copyright © 2011-2022 走看看