sgu 128
论文啊,04年一个人的论文。
原来线段树还可以这么用。
贴代码。
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int MAX=10005; class BIT { public: int a[MAX<<1]; void insert(int pos,int x) { while(pos<MAX*2) { a[pos]+=x; pos+=pos&(-pos); } } int query(int pos) { int ans=0; while(pos) { ans+=a[pos]; pos-=pos&(-pos); } return ans; } }; struct point { int x,y; }; BIT bit; point p[MAX]; int n,s[MAX],pos[MAX],up[MAX],L[MAX]; int find(int x) { if(s[x]!=x) s[x]=find(s[x]); return s[x]; } void Union(int x,int y) { x=find(x); y=find(y); if(x!=y) s[x]=y; } int cmpx(int a,int b) { if(p[a].x!=p[b].x) return p[a].x<p[b].x; return p[a].y<p[b].y; } int cmpy(int a,int b) { if(p[a].y!=p[b].y) return p[a].y<p[b].y; return p[a].x<p[b].x; } int deal() { int ans=0,i,j,k,t; for(int i=0;i<n;i++)s[i]=i; sort(pos,pos+n,cmpx); for(i=0;i<n;i+=2) { j=pos[i]; k=pos[i+1]; if(p[j].x!=p[k].x) return 0; ans+=p[k].y-p[j].y; up[j]=k; Union(j,k); } sort(pos,pos+n,cmpy); for(i=0;i<n;i+=2) { j=pos[i]; k=pos[i+1]; if(p[j].y!=p[k].y) return 0; ans+=p[k].x-p[j].x; L[j]=1; Union(j,k); } k=find(0); for(i=1;i<=n-1;i++) if(find(i)!=k) return 0; sort(pos,pos+n,cmpx); for(int i=0;i<n;i++) { j=pos[i]; k=p[up[j]].y; t=p[j].y; if(up[j]&&bit.query(k+MAX)-bit.query(t+MAX+1)) return 0; if(L[j]) bit.insert(t+MAX+1,1); else bit.insert(t+MAX+1,-1); } return ans; } int main() { scanf("%d",&n); int i; for(int i=0;i<n;i++)scanf("%d%d",&p[i].x,&p[i].y),pos[i]=i; printf("%d\n",deal()); return 0; }