• UESTC_Rain in ACStar 2015 UESTC Training for Data Structures<Problem L>


     

    L - Rain in ACStar

    Time Limit: 9000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    Maybe you have heard of Super Cow AC who is the great general of ACM Empire. However, do you know where he is from?

    This is one of the ten biggest secrets of this world! And it is time to expose the truth!

    Yes, Super Cow AC is from ACStar which is ten million light-year away from our earth. No one, even AC himself, knows how AC came to our home. The only memory in his head is the strange rain in ACStar.

    Because of the special gravity of ACStar, the raindrops in ACStar have many funny features. They have arbitrary sizes, color and tastes. The most interesting parts of the raindrops are their shapes. When AC was very young, he found that all the drops he saw in air were convex hull. Once the raindrops fell to the ground, they would be absorb by the soil.

    .*

    This year is set to be AC-year. In recognition of Great General AC's contribution to our empire, the Emperor decided to build a huge AC park. Inside this park there is a laboratory to simulate the rain in ACStar. As a researcher of this lab, you are appointed to measure the volume of rain absorbed by soil. To simplify this problem, scientists put the rain into two-dimensional plane in which the ground is represented as a straight line and the raindrops are convex polygon. So the area of the graphics stands for the volume of raindrops.

    You will receive two types of instructions:

    1. R P (This type of instructions tell you sufficient information about the raindrops.)
    2. Q A B (Ask you to report the volume of rain absorbed by soil of [A,B].)

    Instructions are given in chronological order.

    Input

    The first line of the inputs is T(no more than 10), which stands for the number of test cases you need to solve.

    After T, the inputs will be each test case. The first line of each case will be N(no more than 25000), representing for the numbers of instructions. The following N lines will give instructions of the two types.

    For each instruction of type 1, it will be followed by a line listing P (at least 3 and at most 5) points representing the convex polygon of the coming raindrop. The points are started by the leftmost point and are given in counterclockwise order. It's guaranteed that no points of the same raindrop are in the same vertical line.

    All numbers are positive integer no more than 1000000000.

    Output

    For each instruction of type 2, output the corresponding result, which should be printed accurately rounded to three decimals.

    It is guaranteed that the result is less than 108.

    Sample input and output

    Sample InputSample Output
    1
    7
    Q 1 100
    R 4
    10 10 11 10 13 11 12 11
    Q 10 11
    Q 1 100
    R 3
    100 20 120 20 110 30
    Q 1 100
    Q 12 120
    0.000
    0.250
    1.000
    1.000
    100.250

    解题报告

    思路很清晰,首先对x离散化,之后的操作就是给某段区间加上一段等差数列.

    同时面积的更新当x1 < x2时添加负面积,x1 > x2添加正面积即可

    使用线段树来维护,线段树存储四个值:

    Double st //左边的增值

    Double ed //右边的增值

    Double k //单位距离的增值

    Double sum //该区间内的S和

    !注意下列几点

    1.建树从[L,R]→[L,mid] + [mid,R],不要+个1.。不然中间那段等于是被黑了

    2.Updata函数!!!!(本题最需注意的地方),一共三种情况:

     

    1:更新区间[ql,qr]在当前区间[l,r]中mid的左边,此时传递不需要任何改变

    2.更新区间[ql,qr]在当前区间[l,r]中mid的右边,此时传递不需要任何改变

    3.更新区间[ql,qr]在当前区间[l,r]中mid的两侧,需要将中间的值计算出来然后再次传递下去,同时修改!!!两边的ql,qr值!!!!!!!!!!!!!!!!!!!!!!

     

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

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <cstdio>
      5 
      6 using namespace std;
      7 const int maxn = 85000 + 500;
      8 int p[maxn*6],hash__[maxn*6];
      9 
     10 typedef struct Query
     11 {
     12   int type,size;
     13   int x[6],y[6],id[6];    
     14 };
     15 
     16 Query q[maxn];
     17 
     18 typedef struct data
     19 {
     20   int l,r,len;
     21   double st,ed,k,sum;
     22   void add(double a,double b,double c)
     23    {
     24          st += a;
     25          ed += b;
     26          k += c;
     27          sum += (a+b)*len*0.50;
     28    }    
     29 };
     30 
     31 data tree[maxn*6];
     32 
     33 
     34 inline double getnext(int x1,int x2,double st,double k)
     35 {
     36    return (double)(p[x2] - p[x1]) * k + st; // x2 > x1
     37 }
     38 
     39 void push_up(int cur)
     40 {
     41   tree[cur].sum = tree[cur*2].sum + tree[cur*2+1].sum;
     42 }
     43 
     44 void push_down(int cur)
     45 {
     46   double st = tree[cur].st;
     47   double ed = tree[cur].ed;
     48   double k = tree[cur].k;
     49   int l = tree[cur].l;
     50   int r = tree[cur].r;
     51   int mid = l + (r-l)/2;
     52   double midval = getnext(l,mid,st,k);
     53   tree[cur*2].add(st,midval,k);
     54   tree[cur*2+1].add(midval,ed,k);
     55   tree[cur].st = 0.;
     56   tree[cur].ed = 0.;
     57   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 , tree[cur].len = p[r]-p[l];
     63   tree[cur].st = tree[cur].ed = tree[cur].k = tree[cur].sum = 0.;
     64   if (r - l > 1)
     65    {
     66          int mid = l + (r-l) / 2;
     67          build_tree(2*cur,l,mid);
     68          build_tree(2*cur+1,mid,r);
     69    }
     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     tree[cur].add(st,ed,k);
     78    else
     79     {
     80        push_down(cur);
     81        int mid = l + (r-l) / 2;
     82        /*
     83        更新有三种情况 
     84        */
     85        if (qr <= mid)
     86         {
     87             updata(ql,qr,2*cur,st,ed,k);  //完全在左边 
     88         }
     89        else if (ql >= mid)
     90         {
     91             updata(ql,qr,2*cur+1,st,ed,k); //完全在右边 
     92         }
     93        else
     94         {
     95             double news = getnext(ql,mid,st,k); //夹在中间
     96             updata(ql,qr,2*cur,st,news,k);
     97             updata(mid,qr,2*cur+1,news,ed,k);
     98         }
     99        push_up(cur);
    100     }
    101 }
    102 
    103 double query(int ql,int qr,int cur)
    104 {
    105    int l = tree[cur].l , r = tree[cur].r;
    106    if (l >= ql && r <= qr)
    107     return tree[cur].sum;
    108    else
    109     {
    110        double res = 0.;
    111        push_down(cur);
    112        int mid = l + (r-l) / 2;
    113        if (mid > ql)
    114         res += query(ql,qr,2*cur);
    115        if (mid < qr)
    116         res += query(ql,qr,2*cur+1);
    117        push_up(cur);
    118        return res;
    119     }
    120 }
    121 
    122 
    123 inline double getk(int x1,int y1,int x2,int y2)
    124 {
    125    return (double)(y2-y1)/(double)(x2-x1);
    126 }
    127 
    128 int main(int argc,char *argv[])
    129 {
    130   int Case;
    131   scanf("%d",&Case);
    132   while(Case--)
    133    {
    134          int n;
    135          int psize = 0;
    136          scanf("%d",&n);
    137          memset(p,0,sizeof(p));
    138          memset(hash__,0,sizeof(hash__));
    139          memset(q,0,sizeof(q));
    140          for(int i = 0 ; i < n ; ++ i)
    141           {
    142                 char oper[10];
    143                 scanf("%s",oper);
    144                 if (oper[0] == 'R')
    145                  {
    146                        q[i].type = 1;
    147                     int size;
    148                     scanf("%d",&size);
    149                     q[i].size = size;
    150                     for(int j = 0 ; j < size ; ++ j)
    151                      {
    152                           int x,y;
    153                           scanf("%d%d",&x,&y);
    154                           q[i].x[j] = x , q[i].y[j] = y , q[i].id[j] = psize;
    155                           p[psize++] = x;
    156                }
    157            }
    158            else
    159            {
    160                  q[i].type = 0;
    161                  int x1,x2;
    162                  scanf("%d%d",&x1,&x2);
    163                  q[i].x[0] = x1;
    164                  q[i].x[1] = x2;
    165                  q[i].id[0] = psize;
    166                  p[psize++] = x1;
    167                  q[i].id[1] = psize;
    168                  p[psize++] = x2;
    169            }
    170        }
    171      memcpy(hash__,p,sizeof(int)*psize);
    172      sort(p,p+psize);
    173      int c = unique(p,p+psize) - p;
    174      for(int i = 0 ; i < psize ; ++ i)
    175       hash__[i] = lower_bound(p,p+c,hash__[i]) - p;
    176      build_tree(1,0,c-1); // Tree set
    177      for(int i = 0 ; i < n ; ++ i)
    178       {
    179             if (q[i].type & 1)
    180              {
    181                   for(int j = 0 ; j < q[i].size ; ++ j)
    182                    {
    183                           int c1 = j;
    184                           int c2 = (j+1)%q[i].size;
    185                           int t1 = hash__[q[i].id[c1]];
    186                           int t2 = hash__[q[i].id[c2]];
    187                           int x1 = q[i].x[c1];
    188                           int y1 = q[i].y[c1];
    189                           int x2 = q[i].x[c2];
    190                           int y2 = q[i].y[c2];
    191                           if (x1 < x2)
    192                            {
    193                               y1 *= -1;
    194                               y2 *= -1;
    195                               double k = getk(x1,y1,x2,y2);  //添加负面积 
    196                        updata(t1,t2,1,y1,y2,k);
    197                     }
    198                    else
    199                     {
    200                        double k = getk(x1,y1,x2,y2);  //添加正面积 
    201                        updata(t2,t1,1,y2,y1,k);
    202                     }
    203               }
    204            }
    205          else
    206           {
    207                      int c1 = 0;
    208                          int c2 = 1;
    209                          int t1 = hash__[q[i].id[c1]];
    210                          int t2 = hash__[q[i].id[c2]];
    211                          printf("%.3lf
    ",query(t1,t2,1));
    212           }
    213       }
    214    }
    215   return 0;
    216 }

     

    No Pain , No Gain.
  • 相关阅读:
    Linux 任务计划
    Linux 进程及作业管理
    算法-动规
    算法-递归
    继承自string 的MyString
    魔兽2-装备
    [小甲鱼]入门学习python笔记 【魔法方法】
    [小甲鱼]入门学习python笔记 【类与对象】
    魔兽1 -备战
    讨厌的大整数加法
  • 原文地址:https://www.cnblogs.com/Xiper/p/4470227.html
Copyright © 2020-2023  润新知