• bzoj 4237稻草人


      按x轴进行分治,将[l,r]分成[l,mid]和[mid+1,r],左下角点x值在[l,mid]中,右上角点x值在[mid+1,r],然后将[l,r]中的所有点按y轴排序,按顺序扫描,若扫描到左下角点,用一个单调栈维护,若扫描到右上角点,用另一个单调栈维护的同时,去维护左下角的单调栈中二分出答案,复杂度O(nlognlogn),程序跑的有点慢

      代码

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<set>
     4 #define N 500010
     5 using namespace std;
     6 int n,i;
     7 long long ans;
     8 int top1,top2,stack1[N],stack2[N];
     9 struct g{
    10     int x,y;
    11 }a[N];
    12 bool cmp(g a,g b)
    13 {
    14     return a.x<b.x;
    15 }
    16 bool cmp1(g a,g b)
    17 {
    18     return a.y<b.y;
    19 }
    20 int ef(int x)
    21 {
    22     int l=1,r=top1,m;
    23     while (l<=r)
    24     {
    25         m=(l+r)>>1;
    26         if (x>a[stack1[m]].y) l=m+1;else r=m-1;
    27     }
    28     return r;
    29 }
    30 void solve(int L,int R,int l,int r)
    31 {
    32     int p,q;
    33     if (L>=R) return;
    34     if (l>=r) return;
    35     int m=(L+R)>>1;
    36     int cnt=l,i;
    37     int t;
    38     for (i=l;i<=r;i++)
    39     if (a[i].x<=m)
    40     {
    41         t=a[i].x;a[i].x=a[cnt].x;a[cnt].x=t;
    42         t=a[i].y;a[i].y=a[cnt].y;a[cnt].y=t;
    43         cnt++;
    44     }    
    45     
    46     if ((l<cnt)&&(cnt<=r))
    47     {
    48         sort(a+l,a+cnt,cmp1);
    49         sort(a+cnt,a+1+r,cmp1);
    50         
    51         top1=0;top2=0;
    52         p=l;q=cnt;
    53         while ((p<cnt)||(q<=r))
    54         {
    55             if ((p==cnt)||((q<=r)&&(a[q].y<a[p].y)))
    56             {
    57                 while ((top2)&&(a[q].x<a[stack2[top2]].x)) top2--;
    58                 ans+=ef(a[q].y)-ef(a[stack2[top2]].y);
    59                 top2++;stack2[top2]=q;q++;
    60             }
    61             else
    62             {
    63                 while ((top1)&&(a[p].x>a[stack1[top1]].x)) top1--;
    64                 top1++;stack1[top1]=p;p++;
    65             }
    66         }
    67         
    68     }
    69     /*
    70     printf("%d %d
    ",L,R);
    71     printf("A:
    ");
    72     for (i=l;i<cnt;i++)
    73     printf("%d %d
    ",a[i].x,a[i].y);
    74         printf("B:
    ");
    75     for (i=cnt;i<=r;i++)
    76     printf("%d %d
    ",a[i].x,a[i].y);
    77      */
    78     solve(L,m,l,cnt-1);
    79     solve(m+1,R,cnt,r);
    80 }
    81 int main()
    82 {
    83     scanf("%d",&n);
    84     for (i=1;i<=n;i++)
    85     {
    86         scanf("%d%d",&a[i].x,&a[i].y);
    87         a[i].y++;
    88     }
    89     sort(a+1,a+1+n,cmp);
    90     for (i=1;i<=n;i++)
    91     a[i].x=i;
    92     solve(1,n,1,n);
    93     printf("%lld
    ",ans);
    94 }

      

  • 相关阅读:
    liunx 用户切换 su sudo
    tomcat 虚拟目录
    如何用vue封装一个防用户删除的平铺页面的水印组件
    webpack入门学习手记(一)
    理解跨域及常用解决方案
    封装一个优雅的element ui表格组件
    使用Koa.js离不开这十个中间件
    深入理解let和var的区别
    编辑器IDE之VSCode
    WTF!! Vue数组splice方法无法正常工作
  • 原文地址:https://www.cnblogs.com/fzmh/p/5382620.html
Copyright © 2020-2023  润新知