poj 3109 Inner Vertices(树状数组)

Inner Vertices

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 1692   Accepted: 446
Case Time Limit: 2000MS

Description

There is an infinite square grid. Some vertices of the grid are black and other vertices are white.

A vertex V is called inner if it is both vertical-inner and horizontal-inner. A vertex V is called horizontal-inner if there are two such black vertices in the same row that V is located between them. A vertex V is
called vertical-inner if there are two such black vertices in the same column that V is located between them.

On each step all white inner vertices became black while the other vertices preserve their colors. The process stops when all the inner vertices are black.

Write a program that calculates a number of black vertices after the process stops.

Input

The first line of the input file contains one integer number n (0 ≤ n ≤ 100 000) — number of black vertices at the beginning.

The following n lines contain two integer numbers each — the coordinates of different black vertices. The coordinates do not exceed 109 by their absolute values.

Output

Output the number of black vertices when the process stops. If the process does not stop, output -1.

Sample Input

4
0 2
2 0
-2 0
0 -2

Sample Output

5

Hint

看了一天多的别人的代码:http://blog.csdn.net/z309241990/article/details/38638243,太弱了

预处理标记第i个点是最上面的还是最下面的点,如果是最下面的点且不是最下面的点,就增加一列被染色的点,

如果是最上面的点且不是最下方的点,肯定少一列被染色的点,最后以y坐标为扫描线,看这段区间有几列被染

色。

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=200000+100;
struct node
{
    int x;
    int y;
}p[maxn];
int a[maxn];
int b[maxn];
int n,cur;
bool vis[maxn],l[maxn],r[maxn];
bool cmp(node u,node v)
{
    if(u.y==v.y)
        return u.x<v.x;
    return u.y<v.y;
}
int low(int k)
{
    return k&(-k);
}
void update(int k,int v)
{
    while(k<maxn)
    {
        a[k]+=v;
        k+=low(k);
    }
}
long long sum(int k)
{
    long long ans=0;
    while(k>0)
    {
        ans+=a[k];
        k-=low(k);
    }
    return ans;
}
void init()//预处理
{
    memset(a,0,sizeof(a));//初始化树状数组
    sort(b,b+cur);
    cur=unique(b,b+cur)-b;//排序,离散化
    for(int i=0;i<n;i++)
    {
        p[i].x=lower_bound(b,b+cur,p[i].x)-b+1;
        p[i].y=lower_bound(b,b+cur,p[i].y)-b+1;
    }
    sort(p,p+n,cmp);//按y排序,已y坐标建扫描线
    memset(vis,0,sizeof(vis));
    for(int i=0;i<n;i++)
    {
       if(!vis[p[i].x])//预处理,k位置在下方第一次出现
       {
           l[i]=1;
           vis[p[i].x]=1;
       }
       else
       l[i]=0;
    }
    memset(vis,0,sizeof(vis));
    for(int i=n-1;i>=0;i--)
    {
        if(!vis[p[i].x])//第k个点的x坐标在上方出现第一次出现
        {
            r[i]=1;
            vis[p[i].x]=1;
        }
        else
        r[i]=0;
    }
}
void solve()
{
    long long ans=0;
    for(int i=0;i<n;)
    {
        int j=i;
       while(j<n-1&&p[j].y==p[j+1].y)//同一条扫描线
       j++;
       for(int k=i;k<=j;k++)
       {
           if(!l[k]&&r[k])// 最上面的点,且下面存在被染色的点
           {
               update(p[k].x,-1);
           }
       }
       if(i!=j)
       ans+=(sum(p[j].x-1)-sum(p[i].x));//p[j].x-1到p[i].x间被改变颜色的点
       if(i<j)
       {
           for(int k=i+1;k<j;k++)
           if(!l[k]&&!r[k])//原来是黑色的点
           ans--;
       }
       while(i<=j)
       {
           if(l[i]&&!r[i])//p[i].x是最底下的位置,且上面有元素,p[i].x上的要被染色
           update(p[i].x,1);
           i++;
       }
    }
    printf("%I64d\n",ans+n);
}
int main()
{
    while(~scanf("%d",&n))
    {
        cur=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            b[cur++]=p[i].x;
            b[cur++]=p[i].y;
        }
        init();
        solve();
    }
    return 0;
}

时间: 2024-08-30 04:20:33

poj 3109 Inner Vertices(树状数组)的相关文章

hdu 1541/poj 2352:Stars(树状数组,经典题)

Stars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4052    Accepted Submission(s): 1592 Problem Description Astronomers often examine star maps where stars are represented by points on a plan

POJ 2892 Tunnel Warfare (树状数组+二分)

题目大意: 三个操作 D pos  将pos位置摧毁,让它和周围不相连. Q pos 问和pos 相连的有多少个村庄. R 修复最近摧毁的村庄. 思路分析: 树状数组记录这个区间有多少个1. 如果  [s-e] 有e-s+1个1 的话.那么这个区间是相连的. 这样的话,我们就可以用二分的办法求出与某个位置最大相连的数量. 还有这里二分 while(l<=r) { if(满足) { ans=mid; l=mid+1; } else r=mid-1; } #include <cstdio>

poj 2155 二维树状数组

http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17721   Accepted: 6653 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. I

poj 2309 BST 使用树状数组的lowbit

如果领悟了树状数组中的lowbit,这道题就是极其简单的,最底层都是奇数,用lowbit(x)寻找x的父亲,然后x的父亲-1就是最大数 至于lowbit是如何计算的嘛,寻找x的父亲,其实就是x+2^x的二进制末尾0的个数. #include<iostream> #include<stdio.h> using namespace std; typedef long long ll; ll lowbit(int x){ return x&(-x); } int main(){

poj 1195 二维树状数组 及二维树状数组模板

http://poj.org/problem?id=1195 求矩阵和的时候,下标弄错WA了一次... 求矩形(x1,y1) (x2,y2)的sum |sum=sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1) 二维树状数组讲解:http://blog.csdn.net/u011026968/article/details/38532117 二维树状数组模板: /*========================================

POJ 2892 Tunnel Warfare [树状数组]

题目链接: http://poj.org/problem?id=2892 题意:一个长度为n的线段,下面m个操作 D x 表示将单元x毁掉 R  表示修复最后毁坏的那个单元 Q x  询问这个单元以及它周围有多少个连续的单元,如果它本身已经被毁坏了就是0 思路: 这道题是经典的线段树入门题目,由于只是进行单点更新, 不涉及区间更新,用树状数组更简洁. 维护两个树状数组,一个是把所有的1进行维护,一个是把所有的0进行维护. 翻转(炸毁或修复)任何一个单元,同时修改这两个树状数组,仅仅是为了 合并 

poj 2299 Ultra-QuickSort 离散化 + 树状数组

题目链接:http://poj.org/problem?id=2299 离散化 + 树状数组 教科书例题般的题目 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <vector> #include <stack> #include <set> #include

poj 2299 Ultra-QuickSort (树状数组+离散化)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 48257   Accepted: 17610 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

POJ 3321 Apple Tree (树状数组)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21191   Accepted: 6436 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been