zoukankan      html  css  js  c++  java
  • POJ

    不存在-1的情况,而且最多一轮就结束了。如果新增加的黑点v0会产生新的黑点v1,那么v0和v1肯定是在一条轴上的,而原来这条轴上已经有黑点了。

    离散以后扫描线统计,往线段上插点,然后查询区间上点数。

    不妨以x为主轴,用一条条平行于y轴的线去扫。

    按照x为主y为副排序以后,记录下标,将下标按y为主排序,为的是把y相同的一系列点变成一个入点(d[id] = 1),一个出点(d[id] = -1),

    可能某个相同y值的点只有一个,所以最后的出点 -= 1。

    点可能有重复,判重的话就标记一下平行x轴的线。

    /*********************************************************
    *            ------------------                          *
    *   author AbyssalFish                                   *
    **********************************************************/
    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    #include<numeric>
    using namespace std;
    
    const int maxn = 1e5;
    
    typedef long long ll;
    typedef pair<int,int> Point;
    #define xc first
    #define yc second
    Point p[maxn];
    int ys[maxn], d[maxn]; //discrete y, scan line
    int n;
    int r[maxn];
    
    bool cmp(int a,int b)
    {
        return p[a].yc < p[b].yc || (p[a].yc == p[b].yc && p[a].xc < p[b].xc);
    }
    
    int C[maxn+1], n0;
    bool vis[maxn+1];
    
    int sum(int x)
    {
        int re = 0;
        while(x > 0){
            re += C[x]; x &= x-1;
        }
        return re;
    }
    
    void add(int x,int d)
    {
        while(x <= n0){
            C[x] += d;
            x += x&-x;
        }
    }
    
    void solve()
    {
        for(int i = 0; i < n; i++){
            scanf("%d%d",&p[i].xc,&p[i].yc);
            r[i] = i;
        }
        //compress
        sort(p,p+n);
        sort(r,r+n,cmp);
        ys[r[0]] = 1; d[r[0]] = 1;
        for(int i = 1; i < n; i++){
            ys[r[i]] = ys[r[i-1]];
            if(p[r[i]].yc != p[r[i-1]].yc) {
                d[r[i-1]] -= 1;
                ys[r[i]]++;
                d[r[i]] = 1;
            }
        }
        n0 = ys[r[n-1]];
        d[r[n-1]] -= 1;
        //memset(C+1,0,sizeof(int)*n0);
    
        ll ans = n;
        for(int i = 0, j; i < n;){
            j = i;
            while(j < n && p[j].xc == p[i].xc) { //不包含端点
                if(d[j] < 0) {
                    vis[ys[j]] = false;
                    add(ys[j], -1);
                }
                j++;
            }
            if(ys[i] < ys[j-1]-1) {
                ans += sum(ys[j-1]-1) - sum(ys[i]);
                for(int k = i+1; k < j-1; k++){ //去重
                    if(vis[ys[k]]) ans--;
                }
            }
            while(i < j) {
                if(d[i] > 0) {
                    add(ys[i],1);
                    vis[ys[i]] = true;
                }
                i++;
            }
        }
        printf("%I64d
    ", ans);
    }
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        scanf("%d", &n);
        solve();
        return 0;
    }
  • 相关阅读:
    CodeForces
    4.15随笔
    oracle新建用户并赋予权限等
    catch时,获取异常信息
    ORACLE 判断是否为数字类型
    UNION ALL用法
    2019.11.7随笔
    oracle 查询锁表和解锁
    2019.11.1随笔
    oracle拼接子查询返回的多个结果
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4977454.html
Copyright © 2011-2022 走看看