• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
XD-TEST
博客园    首页    新随笔    联系   管理    订阅  订阅

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\n",L,R);
71     printf("A:\n");
72     for (i=l;i<cnt;i++)
73     printf("%d %d\n",a[i].x,a[i].y);
74         printf("B:\n");
75     for (i=cnt;i<=r;i++)
76     printf("%d %d\n",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\n",ans);
94 }

 

  

posted @ 2016-04-12 14:40  fzmh  阅读(270)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3