zoukankan      html  css  js  c++  java
  • BZOJ 1818: [Cqoi2010]内部白点

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1818

    扫描线+树状数组。

    首先可以看出题目其实是求有多少点上下左右至少有一个黑点。

    拿x轴离散化,对x轴排一次序,于是我们可以拿出每一条竖线,把它拆成两个事件点,一个+1,一个-1,然后再对y轴排一次序,当作一条事件线段,记下左右端点。

    然后对于这些事件按y轴排一次序,然后树状数组就可以了。

    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define rep(i,l,r) for(int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define low(x) x&(-x)
    #define maxn 100500
    struct data{int x,y,r,k;
    }a[maxn],s[maxn*5];
    int ans,hash[maxn],t[maxn];
    int n,cnt;
    using namespace std;
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    bool cmp(data a,data b){
        if (a.x==b.x) return a.y<b.y;
        return a.x<b.x;
    }
    bool cmp2(data a,data b){
        if (a.y==b.y) return a.x<b.x;
        return a.y<b.y;
    }
    bool cmp3(data a,data b){
        if (a.y==b.y) return a.k<b.k;
        return a.y<b.y;
    }
    int find(int x){
        int l=1,r=n;
        while (l<=r){
            int mid=(l+r)/2;
            if (hash[mid]==x) return mid;
            else if (hash[mid]<x) l=mid+1;
            else r=mid-1;
        }
        return l;
    }
    void insert(int x,int z,int y,int k){
        if (k) {
            s[++cnt].x=find(x); s[cnt].y=z; s[cnt].k=1;
            s[++cnt].x=find(x); s[cnt].y=y; s[cnt].k=-1;
        }
        else {s[++cnt].x=find(x); s[cnt].r=find(z); s[cnt].y=y;}
    }
    void add(int x,int y){
        while (x<=n) {
            t[x]+=y;
            x+=low(x);
        }
    }
    int ask(int x){
        int ans=0;
        while (x){
            ans+=t[x];
            x-=low(x);
        }
        return ans;
    }
    int main(){
        n=read();
        rep(i,1,n){
            a[i].x=read(); a[i].y=read();
            hash[i]=a[i].x;
        }
        sort(hash+1,hash+1+n);
        sort(a+1,a+1+n,cmp);
        rep(i,2,n) if (a[i].x==a[i-1].x) {
            insert(a[i].x,a[i-1].y,a[i].y,1);
        }
        sort(a+1,a+1+n,cmp2);
        rep(i,2,n) if (a[i].y==a[i-1].y){
            insert(a[i-1].x,a[i].x,a[i].y,0);
        }
        sort(s+1,s+1+cnt,cmp3);
        rep(i,1,cnt){
            if (s[i].k==0) ans+=ask(s[i].r-1)-ask(s[i].x);
            else add(s[i].x,s[i].k);
        }
        printf("%d
    ",ans+n);
        return 0;
    }
  • 相关阅读:
    angular-ui-bootstrap的弹出框定义成一个服务的实践(二)
    分享百度文件上传组件webUploader的使用demo
    display的flex属性使用详解
    数组去重(初识ES6)
    在ng中的select的使用方法的讲解
    安装xamp之后,appach、mysql等问题的总结
    python中string.casefold和string.lower区别
    python3数据类型
    MySQL bin-log 日志清理方式
    python终端颜色设置
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5114381.html
Copyright © 2011-2022 走看看