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 }

 

posted @ 2012-11-14 09:37  诺小J  阅读(149)  评论(0编辑  收藏  举报