hdu 1151 覆盖的面积(离散化+类似面积并)

虽然是过,其实我也没想会过,这样做竟不超时,有点厉害

不过也有点慢了,回来再做过

我用了lazy思想,由于每次都要tree_search使得其很慢,网上有些代码是

增加记录域ylenonce,ylenmore分别是记录覆盖一次的长度,覆盖二次以上的长度

这样就不要tree_searh了,快了不知多少~~~

 

我的代码:

#include<iostream> #include<cmath> #include<cstdlib> #define N 1005 using namespace std; struct elem{ double x; double ly; double ry; bool flag; }; struct node{ int l; int r; double m; int cover; bool flag1; }; elem cor[2*N]; node tree[8*N]; double index[2*N]; int len; int n; double res; int cmp(const void *a,const void *b) { if((*(elem*)a).x > (*(elem *)b).x) return 1; else if((*(elem*)a).x == (*(elem *)b).x) return 0; else return -1; } int cmp1(const void *a,const void *b) { if(*(double *)a > *(double *)b) return 1; else if(*(double *)a == *(double *)b) return 0; else return -1; } void init() { int i; int k; double x1,y1,x2,y2; scanf("%d",&n); for(i = 0;i < n;i++){ scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); k = i<<1; cor[k].x = x1; cor[k].ly = y1; cor[k].ry = y2; cor[k].flag = true; cor[k+1].x = x2; cor[k+1].ly = y1; cor[k+1].ry = y2; cor[k+1].flag = false; index[k] = y1; index[k+1] = y2; } qsort(cor,2*n,sizeof(cor[0]),cmp); qsort(index,2*n,sizeof(index[0]),cmp1); len = 0; for(i = 1;i < 2*n;i++){ if(index[i] != index[i-1]) index[++len] = index[i]; } return ; } int find(double x) { int mid; int base = 0,top = len; while(base <= top){ mid = (base+top)/2; if(x < index[mid]) top = mid-1; else if(x > index[mid]) base = mid+1; else return mid; } return -1; } void buid_tree(int k,int left,int right) { int mid; int L,R; tree[k].l = left; tree[k].r = right;//if(tree[k].l == 4 && tree[k].r == 5) cout <<"k:" <<k <<endl; tree[k].m = 0; tree[k].cover = 0; tree[k].flag1 = false; if(tree[k].r-tree[k].l == 1) return ; mid = (tree[k].l+tree[k].r)/2; L = k<<1; R = L+1; buid_tree(L,left,mid); buid_tree(R,mid,right); return ; } void init_m(int k) { int L,R; if(tree[k].cover >= 2){ tree[k].m = index[tree[k].r]-index[tree[k].l]; return ; } L = k<<1; R = L+1; if(tree[k].r-tree[k].l > 1){ tree[k].m = tree[L].m+tree[R].m; return ; } tree[k].m = 0; return ; } void tree_insert(int k,int left,int right) { int mid; int L,R; if(left <= tree[k].l && right >= tree[k].r){ tree[k].cover++;//cout <<'(' <<tree[k].l <<',' <<tree[k].r <<',' <<tree[k].cover <<") "; //init_m(k); tree[k].flag1 = true; return ; } mid = (tree[k].l+tree[k].r)/2; L = k<<1; R = L+1; if(tree[k].cover){ tree[L].cover += tree[k].cover; tree[R].cover += tree[k].cover; tree[k].cover = 0; } if(left < mid) tree_insert(L,left,right); if(right > mid) tree_insert(R,left,right); //init_m(k); return ; } void tree_delete(int k,int left,int right) { int mid; int L,R;//if(tree[k].l == 4 && tree[k].r == 5)cout <<"dgd:" <<tree[k].cover <<endl; if(left <= tree[k].l && right >= tree[k].r){ tree[k].cover--; tree[k].flag1 = true; //init_m(k); return ; } mid = (tree[k].l+tree[k].r)/2; L = k<<1; R = L+1; if(tree[k].cover){ tree[L].cover += tree[k].cover; tree[R].cover += tree[k].cover; tree[k].cover = 0; } if(left < mid) tree_delete(L,left,right); if(right > mid) tree_delete(R,left,right); //init_m(k); return ; } void tree_search(int k) { int L,R; if(tree[k].cover > 1){ //init_m(k); tree[k].m = index[tree[k].r]-index[tree[k].l];//cout <<tree[k].r <<'-' <<tree[k].l << ' '; return ; } if(tree[k].r-tree[k].l == 1){ tree[k].m = 0; return ; } L = k<<1; R = L+1; if(tree[k].cover){ tree[L].cover += tree[k].cover; tree[R].cover += tree[k].cover; tree[k].cover = 0; } tree_search(L); tree_search(R); //init_m(k); tree[k].m = tree[L].m+tree[R].m; return ; } int main() { int tcase; int i;int l,r; scanf("%d",&tcase); while(tcase--){ init(); buid_tree(1,0,len); res = 0; for(i = 0;i < (2*n-1);i++){ l = find(cor[i].ly); r = find(cor[i].ry); if(cor[i].flag){ tree_insert(1,l,r); } else tree_delete(1,l,r); tree_search(1); res += tree[1].m*(cor[i+1].x-cor[i].x); } printf("%.2lf/n",res); } return 0; }

你可能感兴趣的:(struct,tree,delete,search,insert)