Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
扫面线简便做法RT 看了很多题解都是横边和竖边同时统计,要维护的值较多。 其实求竖边或横边之一只用维护当前扫描的总长度,计算与上次的差值。 算完之后在将图形整体旋转90度,再算一遍即可。 甚至可以直接把求面积并的代码改一改就过了。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=1e4+5; int n,l1[MAXN],l2[MAXN],r1[MAXN],r2[MAXN],tr[MAXN<<2],b[MAXN<<2],wz[MAXN<<1],M,ans; struct node { int L,R,h,num; bool operator<(const node &o) const { return h<o.h; } }a[MAXN<<1]; void add(int u,int l,int r,int L,int R,int x) { // cout<<u<<" "<<l<<' '<<r<<' '<<wz[l]<<' '<<wz[r+1]<<' '<<L<<' '<<R<<endl; if(L>=wz[r+1]||wz[l]>=R) return; if(L<=wz[l]&&wz[r+1]<=R) { b[u]+=x; if(b[u]>0) tr[u]=wz[r+1]-wz[l]; else tr[u]=tr[u*2]+tr[u*2+1];//cout<<u<<" "<<l<<" "<<r<<' '<<b[u]<<' '<<tr[u]<<endl; return; } int mid=(l+r)/2; add(u*2,l,mid,L,R,x),add(u*2+1,mid+1,r,L,R,x); if(b[u]>0) tr[u]=wz[r+1]-wz[l]; else tr[u]=tr[u*2]+tr[u*2+1]; // cout<<u<<" "<<l<<" "<<r<<' '<<b[u]<<' '<<tr[u]<<endl; } void solve() { memset(tr,0,sizeof(tr)); memset(b,0,sizeof(b)); M=0; for(int i=1;i<=n;i++) { a[++M]=(node){l1[i],r1[i],l2[i],1},a[++M]=(node){l1[i],r1[i],r2[i],-1}; wz[M-1]=l1[i],wz[M]=r1[i]; } sort(a+1,a+M+1); sort(wz+1,wz+M+1); int lst=0; for(int i=1;i<=M;i++) { add(1,1,M-1,a[i].L,a[i].R,a[i].num); // cout<<i<<' '<<ans<<endl; ans+=abs(tr[1]-lst),lst=tr[1]; } } signed main() { cin>>n; for(int i=1;i<=n;i++) scanf("%lld%lld%lld%lld",&l1[i],&l2[i],&r1[i],&r2[i]); solve(); for(int i=1;i<=n;i++) swap(l1[i],l2[i]),swap(r1[i],r2[i]); solve(); cout<<ans; return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator