hdu 3340 线段树思路活用
开始看到这道题目的时候,神题啊。。 想了一个下午,没思路。。。
后面到网上一看这位大哥的解说,豁然开朗http://blog.csdn.net/gotoac/article/details/7588254
每个区间分割多边形是可能是三角形或者梯形或者四边形,都是上底+下底乘高除2,这个小学就会的东西,看来现在还是不能够活用的啊。。。。
View Code
1 #include<iostream> 2 #include<stdlib.h> 3 #include<cstdio> 4 #include<algorithm> 5 using std::swap; 6 using std::sort; 7 using std::unique; 8 const int N = 25005; 9 struct order 10 { 11 int x[6],y[6],s; 12 }Order[N]; 13 int X[N*5]; 14 double sum[N<<4],lh[N<<4],rh[N<<4],len[N<<4]; 15 int Fin(int k,int len) 16 { 17 int l=0,r=len; 18 while(l<r) 19 { 20 int m=(r+l)>>1; 21 if(X[m]==k)return m; 22 if(X[m]>k)r=m-1; 23 else l=m+1; 24 } 25 return l; 26 } 27 double Cal(double ly,double ry,int d,int l,int r) 28 { 29 return ly+(1.0*(r-l)*(ry-ly)/d); 30 } 31 void build(int t,int l,int r) 32 { 33 len[t]=X[r+1]-X[l]; 34 sum[t]=lh[t]=rh[t]=0; 35 if(l==r)return ; 36 int m=(r+l)>>1; 37 build(t<<1,l,m); 38 build(t<<1|1,m+1,r); 39 } 40 void PushDown(int t,int l,int r) 41 { 42 if(lh[t]||rh[t]) 43 { 44 int t1=t<<1; 45 int t2=t1|1; 46 int m=(r+l)>>1; 47 double mh=Cal(lh[t],rh[t],len[t],X[l],X[m+1]); 48 lh[t1]+=lh[t]; 49 rh[t1]+=mh; 50 lh[t2]+=mh; 51 rh[t2]+=rh[t]; 52 sum[t1]+=len[t1]*(lh[t]+mh)/2; 53 sum[t2]+=len[t2]*(rh[t]+mh)/2; 54 lh[t]=rh[t]=0; 55 } 56 } 57 void PushUp(int t) 58 { 59 sum[t]=sum[t<<1]+sum[t<<1|1]; 60 } 61 void update(int t,int l,int r,int L,int R,double ly,double ry) 62 { 63 if(L<=l&&r<=R) 64 { 65 double ld=Cal(ly,ry,X[R+1]-X[L],X[L],X[l]); 66 double rd=Cal(ly,ry,X[R+1]-X[L],X[L],X[r+1]); 67 lh[t]+=ld; 68 rh[t]+=rd; 69 sum[t]+=len[t]*(ld+rd)/2; 70 return ; 71 } 72 PushDown(t,l,r); 73 int m=(r+l)>>1; 74 if(L<=m)update(t<<1,l,m,L,R,ly,ry); 75 if(R>m)update(t<<1|1,m+1,r,L,R,ly,ry); 76 PushUp(t); 77 } 78 double query(int t,int l,int r,int L,int R) 79 { 80 if(L<=l&&r<=R)return sum[t]; 81 PushDown(t,l,r); 82 int m=(r+l)>>1; 83 double ans=0; 84 if(L<=m)ans+=query(t<<1,l,m,L,R); 85 if(R>m)ans+=query(t<<1|1,m+1,r,L,R); 86 return ans; 87 } 88 int main() 89 { 90 int t,n; 91 char ord[5]; 92 scanf("%d",&t); 93 while(t--) 94 { 95 scanf("%d",&n); 96 int topx=0; 97 for(int i=0;i<n;i++) 98 { 99 scanf("%s",ord); 100 if(ord[0]=='Q') 101 { 102 Order[i].s=0; 103 scanf("%d%d",&Order[i].x[0],&Order[i].y[0]); 104 X[topx++]=Order[i].x[0]; 105 X[topx++]=Order[i].y[0]; 106 } 107 else 108 { 109 scanf("%d",&Order[i].s); 110 for(int j=0;j<Order[i].s;j++) 111 { 112 scanf("%d%d",&Order[i].x[j],&Order[i].y[j]); 113 X[topx++]=Order[i].x[j]; 114 } 115 Order[i].x[Order[i].s]=Order[i].x[0]; 116 Order[i].y[Order[i].s]=Order[i].y[0]; 117 Order[i].s++; 118 } 119 } 120 sort(X,X+topx); 121 topx=unique(X,X+topx)-X; 122 build(1,0,topx-1); 123 124 for(int i=0;i<n;i++) 125 { 126 if(Order[i].s==0) 127 { 128 if(Order[i].x[0]>Order[i].y[0])swap(Order[i].x[0],Order[i].y[0]); 129 int L=Fin(Order[i].x[0],topx-1); 130 int R=Fin(Order[i].y[0],topx-1)-1; 131 printf("%.3lf\n",L>R?0:query(1,0,topx-1,L,R)); 132 } 133 else 134 { 135 for(int j=1;j<Order[i].s;j++) 136 { 137 int L=Fin(Order[i].x[j-1],topx-1); 138 int R=Fin(Order[i].x[j],topx-1); 139 if(R>L)update(1,0,topx-1,L,R-1,-1.0*Order[i].y[j-1],-1.0*Order[i].y[j]); 140 if(L>R)update(1,0,topx-1,R,L-1,1.0*Order[i].y[j],1.0*Order[i].y[j-1]); 141 } 142 } 143 } 144 } 145 return 0; 146 }