码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC_冰雪奇缘 CDOJ 843

时间:2015-04-24 22:33:12      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

艾莎女王又开始用冰雪魔法盖宫殿了。

她决定先造一堵墙,于是释放魔法让形为直角梯形的冰砖从天而降,定入冻土之中。

现在你将回答女王的询问:某段冻土上冰砖的面积。

注:多块冰砖之间会互相重叠,重叠部分要多次计算。

技术分享

 

Input

第一行一个整数n,表示有n个冰砖先后定入了冻土之中。

冻土上刚开始并没有冰砖。

接下来n行,每行6个整数,x1i,h1i,x2i,h2i,li,ri。

表示一次如图所示的冰砖下落,并询问在这之后,落在[li,ri]内冰砖的总面积。

2≤n≤100000,−108≤li<ri≤108,−108≤x1i<x2i≤108,0≤h1i,h2i≤10000,x2i−x1i≤105

 

Output

输出n行,每行输出一个浮点数,作为对该询问的回答。误差小于1e-6的回答都被当作正确回答

 

 

解题报告

 

首先由于范围很大,我们对X轴上的点进行离散化

 

注意到这个四边形就是给一段区间增加一段等差数列.

 

并且注意到等差数列叠加后依然还是等差数列

 

那么我们在线段树中就存储四个值:

 

1.double st; //该区间左端应该加的值

 

2.double ed; //该区间右端应该加的值

 

3.double k;  //等差数列的k值,不多说

 

4.double sum; //该区间的面积之和

 

那么面积我们就转换成梯形计算:

  

  SUM = (st + ed) * 0.5 * Len; //注意到这个Len是这个区间的实际长度!!

  

这样.

   

  还有两点需要注意!

  

  1.区间建立的时候是[L,R] → [L,mid] + [mid,R]

   

  2. updata操作有三种情况,三种情况的更新各不同,这点需要注意

  技术分享

 分别对应ql ,qr 在mid 的左 / 右 / 中三种情况,需分开讨论

 注意上以上几点,那么本题也就迎刃而解了.

  

   

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 using namespace std;
  6 const int maxn = 1e5 + 500;
  7 int n;
  8 int pos[maxn*9];
  9 int hashpos[maxn*9];
 10 
 11 typedef struct Query
 12 {
 13 int l,r,x1,y1,x2,y2,id[6];
 14 };
 15 
 16 typedef struct Data
 17 {
 18 int l,r,len;
 19 double sum,st,ed,k;
 20 void updata(const double &x,const double &y,const double &z)
 21  {
 22      st += x;
 23      ed += y;
 24      k += z;
 25      sum += (double)(x+y)*len*0.5;
 26  }
 27 };
 28 
 29 
 30 Query q[maxn*2];
 31 Data tree[maxn*6];
 32 int size = 0;
 33 
 34 
 35 void push_up(int cur)
 36 {
 37    tree[cur].sum = tree[cur*2].sum + tree[cur*2+1].sum;
 38 }
 39 
 40 inline double get_(int x1,int x2,double st,double k)
 41 {
 42    return (double)(hashpos[x2]-hashpos[x1]) * k + st;
 43 }
 44 
 45 
 46 void push_down(int cur)
 47 {
 48   double st = tree[cur].st;
 49   double ed = tree[cur].ed;
 50   double k = tree[cur].k;
 51   int l = tree[cur].l;
 52   int r = tree[cur].r;
 53   int mid = l + (r-l)/2;
 54   double news = get_(tree[cur].l,mid,st,k);
 55   tree[2*cur].updata(st,news,k);
 56   tree[2*cur+1].updata(news,ed,k);
 57   tree[cur].st = tree[cur].ed = tree[cur].k = 0.;
 58 }
 59 
 60 void build_tree(int cur,int l,int r)
 61 {
 62    tree[cur].l = l , tree[cur].r = r;
 63    tree[cur].len = hashpos[r] - hashpos[l];
 64    tree[cur].st = tree[cur].ed = tree[cur].k = tree[cur].sum = 0.;
 65    if (r -l > 1)
 66     {
 67         int mid = l + (r-l)/2;
 68         build_tree(2*cur,l,mid);
 69         build_tree(2*cur+1,mid,r);
 70     }
 71 }
 72 
 73 void updata(int ql,int qr,int cur,double st,double ed,double k)
 74 {
 75    int l = tree[cur].l , r = tree[cur].r;
 76    if (l >= ql && r <= qr)
 77     {
 78         tree[cur].updata(st,ed,k);
 79     }
 80    else
 81     {
 82         push_down(cur);
 83         int mid = l + (r-l) / 2;
 84         //三种情况,分开讨论
 85         if (qr <= mid) updata(ql,qr,2*cur,st,ed,k);
 86         else if(ql >= mid) updata(ql,qr,2*cur+1,st,ed,k);
 87         else
 88          {
 89              double news = get_(ql,mid,st,k);
 90              updata(ql,mid,2*cur,st,news,k);
 91              updata(mid,qr,2*cur+1,news,ed,k);
 92          }
 93         push_up(cur);
 94     }
 95 }
 96 
 97 double query(int ql,int qr,int cur)
 98 {
 99    int l = tree[cur].l , r = tree[cur].r;
100    if (l >= ql && r <= qr)
101     return tree[cur].sum;
102    else
103     {
104         push_down(cur);
105         double res = 0.;
106         int mid = l + (r-l)/2;
107         if (mid > ql)
108          res += query(ql,qr,2*cur);
109         if (mid < qr)
110          res += query(ql,qr,2*cur+1);
111         push_up(cur);
112         return res;
113     }
114 }
115 
116 inline double getk(int x1,int x2,int y1,int y2)
117 {
118    return (double)(y2-y1) / (double)(x2-x1);
119 }
120 
121 
122 
123 int main(int argc,char *argv[])
124 {
125   scanf("%d",&n);
126   for(int i = 0 ; i < n ; ++ i)
127    {
128          int x1,y1,x2,y2,l,r;
129          scanf("%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&l,&r);
130          q[i].id[0] = size;
131          pos[size++] = x1;
132          q[i].id[1] = size;
133          pos[size++] = x2;
134          q[i].id[2] = size;
135          pos[size++] = l;
136          q[i].id[3] = size;
137          pos[size++] = r;
138          q[i].x1 = x1;
139          q[i].x2 = x2;
140          q[i].y1 = y1;
141          q[i].y2 = y2;
142          q[i].l = l;
143          q[i].r = r;
144    }
145   memcpy(hashpos,pos,sizeof(int)*size);
146   sort(hashpos,hashpos+size);
147   int c = unique(hashpos,hashpos+size) - hashpos;
148   for(int i = 0 ; i < size ; ++ i)
149    pos[i] = lower_bound(hashpos,hashpos+c,pos[i]) - hashpos;
150   build_tree(1,0,c-1);
151   for(int i = 0 ; i < n ; ++ i)
152    {
153          int x1 = q[i].x1;
154          int y1 = q[i].y1;
155          int x2 = q[i].x2;
156          int y2 = q[i].y2;
157          double k = getk(x1,x2,y1,y2);
158          updata(pos[q[i].id[0]],pos[q[i].id[1]],1,(double)y1,(double)y2,k);
159          double res = query(pos[q[i].id[2]],pos[q[i].id[3]],1);
160          printf("%.9lf\n",res);
161    }
162   return 0;
163 }

 

UESTC_冰雪奇缘 CDOJ 843

标签:

原文地址:http://www.cnblogs.com/Xiper/p/4454623.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!