Shu-How Zの小窝

Loading...

CQOI2010内部白点

原题

因为要行程内部白点,上下左右都至少有一个内部黑点。而内部黑点是有限的,所以不可能无限制增长下去。

增长多次也是假的。如果增长一次后,又有新的点可以增长,那这个点一定已经在第一次增长时增长完了。

于是就把问题转化成了:在黑点增长一次后,有多少黑点。

一个点如果变黑,必定在两条黑点连线的交点上。所以可以求出所有竖着的线段的上界和下界。按照y坐标从大到小排序,第二关键字是按x坐标从小到大。开一个线段树,存所有的x坐标,里面维护:对于这个x坐标,当前的y坐标是否在这个x轴线段上(上界与下界内),若是,则值为1(1个黑点),若不是,则值为0(0个黑点)。在按普通区间和线段树的板子写就行

注意离散化。

\(ACcode:\)

#include<bits/stdc++.h>
#define ls (p<<1)
#define rs ((p<<1)|1)
#define mid ((l+r)>>1)
#define inf 0x3f3f3f3f
using namespace std;
const int N=1e5;
int n,m;
struct Node{
    int x,y;
}a[N+5];
struct line{
    int up,down;
}l[N+5];
int temp[N+5];
int cnt;
bool cmp(Node a,Node b){return a.y==b.y?a.x<b.x:a.y>b.y;}
struct edge{
    int ans;
}tree[4*N+5];
void update(int p,int l,int r,int node,int val)
{
    tree[p].ans+=val;
    if(l==node&&r==node) return;
    if(node<=mid) update(ls,l,mid,node,val);
    else update(rs,mid+1,r,node,val);
}
int query(int p,int l,int r,int left,int right)
{
    if(l==left&&r==right)
    {
        return tree[p].ans;
    }
    int res=0;
    if(right<=mid) res=query(ls,l,mid,left,right);
    else if(left>mid) res=query(rs,mid+1,r,left,right);
    else res=query(ls,l,mid,left,mid)+query(rs,mid+1,r,mid+1,right);
    return res;
}
int ans=0;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].x>>a[i].y;
        temp[i]=a[i].x;
        l[i].up=-inf;
        l[i].down=inf;
    }
    stable_sort(a+1,a+n+1,cmp);
    stable_sort(temp+1,temp+n+1);
    m=unique(temp+1,temp+n+1)-temp-1;
    for(int i=1;i<=n;i++)
    {
        a[i].x=lower_bound(temp+1,temp+m+1,a[i].x)-temp;
        l[a[i].x].up=max(l[a[i].x].up,a[i].y);
        l[a[i].x].down=min(l[a[i].x].down,a[i].y);
    }
    int L=a[1].x;
    a[n+1].y==inf;
    for(int i=1;i<=n;i++)
    {
        if(a[i].y==l[a[i].x].up) update(1,1,m,a[i].x,1);
        if(a[i].y==l[a[i].x].down)
        {
            ans++;
            update(1,1,m,a[i].x,-1);
        }
        if(a[i].y!=a[i+1].y)
        {
            ans+=query(1,1,m,L,a[i].x);
            L=a[i+1].x;
        }
    }
    cout<<ans<<"\n";
    return 0;
}
posted @ 2025-02-23 20:11  wangyanxiao  阅读(26)  评论(0)    收藏  举报