bzoj4237: 稻草人

这是一个挺好的题啊
话说应该算cdq分治吧,好久没写过了QwQ

ORZ

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=200005;
const int MAX=1<<30;
struct qq
{
    int x,y;
}s[N];
int n;
bool cmp (qq a,qq b){return a.x<b.x;}
bool cmp1 (qq a,qq b){return a.y>b.y;}
LL ans=0;
qq q1[N],q2[N];//左边    右边的队列
int find (int x,int y)//问现在的队列中比y大的
{
    int l=1,r=y;
    while (l<=r)
    {
        int mid=(l+r)>>1;
        if (q2[mid].y<=x)
            r=mid-1;
        else l=mid+1;
    }
    return r;
}
void solve (int l,int r)//这一段数值的答案 
{
    if (l>=r) return ;
    int mid=(l+r)>>1;
    solve(l,mid);solve(mid+1,r);
    sort(s+l,s+mid+1,cmp1);sort(s+mid+1,s+1+r,cmp1);
    int ed=0,ed1=0,p=mid+1;
    q1[0].y=q2[0].y=MAX;
    for (int u=l;u<=mid;u++)
    {
        while (p<=r&&s[p].y>s[u].y)
        {
            while (ed1!=0&&s[p].x<q2[ed1].x)    ed1--;
            q2[++ed1]=s[p];
            p++;
        }
        while (ed!=0&&s[u].x>q1[ed].x) ed--;
        q1[++ed]=s[u];
        int l=find(q1[ed-1].y,ed1)+1;
        int r=find(q1[ed].y,ed1);
        if (l<=r) ans=ans+(LL)(r-l+1);
    }
}
int main()
{
    scanf("%d",&n);
    for (int u=1;u<=n;u++)
        scanf("%d%d",&s[u].x,&s[u].y);
    sort(s+1,s+1+n,cmp);
    solve(1,n);
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值