[Cqoi2010]内部白点
Time Limit:10000MS Memory Limit:65536K
Total Submit:63 Accepted:32
Case Time Limit:2000MS
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
Sample Output
Source
注意到每个黑点只要当前不能被染黑以后也不会被染黑。。就OK了。。
只要弄个扫描线搞一下,再用树状数组维护部分和就OK了
详情见代码吧。。
Code:
#include <vector>
#include <algorithm>
#include <utility>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <map>
#include <cstring>
#include <set>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define Debug(x) cout<<#x<<"="<<x<<endl;
#define For(i,l,r) for(int i=l;i<=r;i++)
#define All(x) x.begin(),x.end()
const int inf=~0U>>1,maxn=100000;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n;
struct Index
{
int A[maxn],n;
Index(){n=0;}
void Add(int x){A[n++]=x;}
void DoIt()
{
sort(A,A+n);
n=unique(A,A+n)-A;
}
int operator[](int v)
{
return lower_bound(A,A+n,v)-A;
}
}IndexY;
struct TreeArray
{
int A[maxn],n;
TreeArray()
{
memset(A,0,sizeof A);
}
void SetN(int _n){n=_n;}
void Add(int x,int d)
{
for(x++;x<=n;x+=x&-x)
A[x-1]+=d;
}
int Sum(int x)
{
int ret=0;
for(x++;x;x-=x&-x)
ret+=A[x-1];
return ret;
}
}TA;
map<int,vector<int> > Ps;
typedef map<int,vector<int> >::iterator mit;
int Left[maxn]={},Right[maxn]={};
void Init()
{
scanf("%d",&n);int x,y;
rep(i,n)
{
scanf("%d%d",&x,&y);
Ps[x].pb(y);
IndexY.Add(y);
}
IndexY.DoIt();
for(mit it=Ps.begin();it!=Ps.end();it++)
{
vector<int>&V=it->second;
rep(i,V.size())V[i]=IndexY[V[i]],Right[V[i]]++;
sort(All(V));
}
}
#define OK(x) (Left[x]&&Right[x])
inline void Update(int x,int d)
{
int s=OK(x);
if(d==1)Left[x]++;
else Right[x]–;
TA.Add(x,OK(x)-s);
}
void Solve()
{
ll ans=0;
TA.SetN(IndexY.n);
for(mit it=Ps.begin();it!=Ps.end();it++)
{
vector<int>&V=it->second;
int n=V.size();
rep(i,n)Update(V[i],-1);
ans+=TA.Sum(V[n-1])-TA.Sum(V[0]-1);
rep(i,n)ans-=OK(V[i]);
rep(i,n)Update(V[i],1);
}
cout<<ans+n<<endl;
}
int main()
{
//freopen("in","r",stdin);
Init();
Solve();
}
5数据范围36%的数据满足:n < = 50064%的数据满足:n < = 30000100%的数据满足:n < = 10000040 22 0-2 00 -2
膜拜之、 当时现场写了近200行的代码、只拿了95分、= =
回复葉鵼菻:主要是能用STL囧。。否则的话我还得写歌BinarySearh和Qsort。。也差不多了。。
….c 3358B写完了………….调了一上午 写得我欲哭无泪….看到WJMZBMR神犇的代码…我又有泪了….ORZ WJMZBMR……….