由于05年的那道论文里的题我找不到(懒得找)
然后拿这题代替了一下,验证我算法的正确性
首先这题线段树是最优解就不用说了。
然后论文里有个坑爹题,把矩形染上颜色然后求每种颜色的面积。
这个时候线段树就要n^2*logn的复杂度啦
而下面这种方法依旧是n^2(然而我并没有找到那道题)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct seg{ double l,r,x; int id,a,b; bool operator < (const seg &rhs)const{ return x<rhs.x; } }s[205]; bool ex[105]; int pa[205]; double hash[205]; int find(int x){ return pa[x]==x?x:pa[x]=find(pa[x]); } void merge(int u,int v){ u=find(u);v=find(v); if(u!=v){ if(u>v)swap(u,v); pa[u]=v; } } double addseg(seg s){ int last=s.a; double ans=0; for(int u=s.a;u<=s.b;){ ans+=hash[u]-hash[last]; merge(u,last); last=find(u); u=last+1; } return ans; } int n; double work(){ double ans=0; for(int i=1;i<=2*n;i++)pa[i]=i; for(int i=1;i<=2*n;i++) if(ex[s[i].id]) ans+=addseg(s[i]); return ans; } double solve(){ double ans=0; int j; for(int i=1;i<=2*n;i=j){ j=i; while(j<=2*n&&s[i].x==s[j].x) ex[s[j++].id]^=1; ans+=work()*(s[j].x-s[i].x); } return ans; } void init(){ double x1,x2,y1,y2; for(int i=1;i<=n;i++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); s[2*i]=(seg){y1,y2,x1,i,0,0}; s[2*i-1]=(seg){y1,y2,x2,i,0,0}; hash[2*i]=y1;hash[2*i-1]=y2; } sort(hash+1,hash+2*n+1);sort(s+1,s+1+2*n); for(int i=1;i<=2*n;i++) s[i].a=lower_bound(hash+1,hash+1+2*n,s[i].l)-hash, s[i].b=lower_bound(hash+1,hash+1+2*n,s[i].r)-hash; } int main(){ //freopen("a.in","r",stdin); while(scanf("%d",&n)&&n){ init(); printf("%.2lf\n",solve()); } return 0; }