zoukankan      html  css  js  c++  java
  • UESTC_冰雪奇缘 CDOJ 843

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

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

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

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

     

    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
    ",res);
    161    }
    162   return 0;
    163 }
    No Pain , No Gain.
  • 相关阅读:
    用spring boot 来创建第一个application
    Entily实体类
    ORM
    lambda expression
    Domain logic approochs
    mysql的数据类型(Data type)
    Backup &recovery备份和还原
    spring AOP Capability and goals
    CDI Features
    Tomcat的配置与安装
  • 原文地址:https://www.cnblogs.com/Xiper/p/4454623.html
Copyright © 2011-2022 走看看