真是道好题,题解在这里http://hzwer.com/?s=1818。
说一下WA点吧,加线段的时候要分开加,不能一列只加一个,因为会把中间的初始黑点统计到。
一定是统计第一秒中染的黑点+初始黑点。
cmp函数比较难写。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<map> #define maxn 100010 using namespace std; struct yts { int x,y; }a[maxn]; struct yts1 { int typ,y1,x1,x2; }h[1000010]; map<int,int> p1,p2; int n,m,cnt,ans; int t[maxn]; int c[maxn]; bool cmp1(yts x,yts y) { return x.x<y.x || (x.x==y.x && x.y<y.y); } bool cmp2(yts x,yts y) { return x.y<y.y || (x.y==y.y && x.x<y.x); } bool cmp3(yts1 x,yts1 y) { return x.y1<y.y1 || (x.y1==y.y1 && x.typ<y.typ); } void addedge(int f,int x,int y,int z)//1横0竖 { if (f==1) { h[++cnt].typ=0;h[cnt].y1=x;h[cnt].x1=y;h[cnt].x2=z; } else { h[++cnt].typ=1;h[cnt].y1=y;h[cnt].x1=x; h[++cnt].typ=-1;h[cnt].y1=z;h[cnt].x1=x; } } int lowbit(int x) { return x&(-x); } int query(int i) { int ans=0; while (i) { ans+=c[i]; i-=lowbit(i); } return ans; } void add(int i,int x) { while (i<=n) { c[i]+=x; i+=lowbit(i); } } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y); for (int i=1;i<=n;i++) t[i]=a[i].x; sort(t+1,t+n+1); int mx=1;p1[t[1]]=1; for (int i=2;i<=n;i++) if (t[i]!=t[i-1]) p1[t[i]]=++mx; for (int i=1;i<=n;i++) t[i]=a[i].y; sort(t+1,t+n+1); mx=1;p2[t[1]]=1; for (int i=2;i<=n;i++) if (t[i]!=t[i-1]) p2[t[i]]=++mx; for (int i=1;i<=n;i++) a[i].x=p1[a[i].x],a[i].y=p2[a[i].y]; sort(a+1,a+n+1,cmp1); for (int i=2;i<=n;i++) if (a[i].x==a[i-1].x) addedge(0,a[i].x,a[i-1].y,a[i].y); sort(a+1,a+n+1,cmp2); for (int i=2;i<=n;i++) if (a[i].y==a[i-1].y) addedge(1,a[i].y,a[i-1].x,a[i].x); sort(h+1,h+cnt+1,cmp3); for (int i=1;i<=cnt;i++) { if (!h[i].typ) ans+=query(h[i].x2-1)-query(h[i].x1); else add(h[i].x1,h[i].typ); } printf("%d\n",ans+n); return 0; }