zoukankan      html  css  js  c++  java
  • [CQOI2010]内部白点

    Description

    无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点)。每秒钟,所有内部白点同时变黑,直到不存在内部白点为止。你的任务是统计最后网格中的黑点个数。 内部白点的定义:一个白色的整点P(x,y)是内部白点当且仅当P在水平线的左边和右边各至少有一个黑点(即存在x1 < x < x2使得(x1,y)和(x2,y)都是黑点),且在竖直线的上边和下边各至少有一个黑点(即存在y1 < y < y2使得(x,y1)和(x,y2)都是黑点)。

    Input

    输入第一行包含一个整数n,即初始黑点个数。以下n行每行包含两个整数(x,y),即一个黑点的坐标。没有两个黑点的坐标相同,坐标的绝对值均不超过109。

    Output

    输出仅一行,包含黑点的最终数目。如果变色过程永不终止,输出-1。

    Sample Input

    4
    0 2
    2 0
    -2 0
    0 -2

    Sample Output

    5

    数据范围
    36%的数据满足:n < = 500
    64%的数据满足:n < = 30000
    100%的数据满足:n < = 100000
    首先不存在无解,且加的能加黑点就是原图的内部白点
    枚举每一条竖线(x相同)
    显然竖线分成几段
    如果一段中存在左右都有点的y,那么答案+1
    用树状数组维护这个区间内满足条件的点数
    令$l_i$为纵坐标为i,左边有多少点,$r_i$类似
    如果$l[y]=0$那么y之后就可以构成一个答案+1
    如果$r[y]=1$那么y之后就不再构成答案-1
    然后区间求和[a[i-1].y+1,a[i].y-1](黑点不能变成黑点)
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long lol;
     8 struct ZYYS
     9 {
    10   int x,y;
    11 }a[800001];
    12 int t[800001],num,l[800001],r[800001],n;
    13 lol c[800001],ans;
    14 bool cmp(ZYYS a,ZYYS b)
    15 {
    16   if (a.x==b.x) return a.y<b.y;
    17   return a.x<b.x;
    18 }
    19 void update(int x,lol y)
    20 {
    21   while (x<=num)
    22     {
    23       c[x]+=y;
    24       x+=(x&(-x));
    25     }
    26 }
    27 lol query(int x)
    28 {
    29   lol s=0;
    30   while (x)
    31     {
    32       s+=c[x];
    33       x-=(x&(-x));
    34     }
    35   return s;
    36 }
    37 int main()
    38 {int i,ed,j;
    39   cin>>n;
    40   for (i=1;i<=n;i++)
    41     {
    42       scanf("%d%d",&a[i].x,&a[i].y);
    43       t[++num]=a[i].x;t[++num]=a[i].y;
    44     }
    45   sort(t+1,t+num+1);
    46   num=unique(t+1,t+num+1)-t-1;
    47   for (i=1;i<=n;i++)
    48     {
    49       a[i].x=lower_bound(t+1,t+num+1,a[i].x)-t;
    50       a[i].y=lower_bound(t+1,t+num+1,a[i].y)-t;
    51     }
    52   sort(a+1,a+n+1,cmp);
    53   for (i=1;i<=n;i++)
    54     r[a[i].y]++;
    55   ans=n;
    56   for (i=1;i<=n;i=ed)
    57     {
    58       ed=i;
    59       while (ed<=n&&a[ed].x==a[i].x) ed++;
    60       for (j=i;j<ed;j++)
    61     {
    62       int y=a[j].y;
    63       if (l[y]==0)
    64         update(y,1);
    65       if (r[y]==1)
    66         update(y,-1);
    67       l[y]++;r[y]--;
    68       if (j>i&&j<ed)
    69         ans+=query(y-1)-query(a[j-1].y);
    70     }
    71     }
    72   cout<<ans<<endl;
    73 }

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long lol;
    struct ZYYS
    {
      int x,y;
    }a[800001];
    int t[800001],num,l[800001],r[800001],n;
    lol c[800001],ans;
    bool cmp(ZYYS a,ZYYS b)
    {
      if (a.x==b.x) return a.y<b.y;
      return a.x<b.x;
    }
    void update(int x,lol y)
    {
      while (x<=num)
        {
          c[x]+=y;
          x+=(x&(-x));
        }
    }
    lol query(int x)
    {
      lol s=0;
      while (x)
        {
          s+=c[x];
          x-=(x&(-x));
        }
      return s;
    }
    int main()
    {int i,ed,j;
      freopen("1818.in","r",stdin);
      freopen("1818.out","w",stdout);
      cin>>n;
      for (i=1;i<=n;i++)
        {
          scanf("%d%d",&a[i].x,&a[i].y);
          t[++num]=a[i].x;t[++num]=a[i].y;
        }
      sort(t+1,t+num+1);
      num=unique(t+1,t+num+1)-t-1;
      for (i=1;i<=n;i++)
        {
          a[i].x=lower_bound(t+1,t+num+1,a[i].x)-t;
          a[i].y=lower_bound(t+1,t+num+1,a[i].y)-t;
        }
      sort(a+1,a+n+1,cmp);
      for (i=1;i<=n;i++)
        r[a[i].y]++;
      ans=n;
      for (i=1;i<=n;i=ed)
        {
          ed=i;
          while (ed<=n&&a[ed].x==a[i].x) ed++;
          for (j=i;j<ed;j++)
        {
          int y=a[j].y;
          if (l[y]==0)
            update(y,1);
          if (r[y]==1)
            update(y,-1);
          l[y]++;r[y]--;
          if (j>i&&j<ed)
            ans+=query(y-1)-query(a[j-1].y);
        }
        }
      cout<<ans<<endl;
    }

  • 相关阅读:
    4408: [Fjoi 2016]神秘数
    UOJ #35. 后缀排序[后缀数组详细整理]
    POJ 2887 Big String
    搜索过滤grep(win下为findstr)
    解决putty自动断开的问题
    > >> 将错误输出到文件
    环境变量
    端口被占用,查看并杀死占用端口的进程
    查找文件路径find
    【vim使用】
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8718003.html
Copyright © 2011-2022 走看看