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)

Submit Status

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 Input Sample 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\n",query(t1,t2,1));
212           }
213       }
214    }
215   return 0;
216 }
时间: 2024-12-29 01:01:39

UESTC_Rain in ACStar 2015 UESTC Training for Data Structures<Problem L>的相关文章

UESTC_秋实大哥与战争 2015 UESTC Training for Data Structures&lt;Problem D&gt;

D - 秋实大哥与战争 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 男儿何不带吴钩,收取关山五十州. 征战天下是秋实大哥一生的梦想,所以今天他又在练习一个对战游戏. 秋实大哥命令所有士兵从左到右排成了一行来抵挡敌人的攻击. 敌方每一次会攻击一个士兵,这个士兵就会阵亡,整个阵列就会从这个位置断开:同时有的时候已阵亡的士兵会受人赢气息感染而复活. 秋

UESTC_秋实大哥与快餐店 2015 UESTC Training for Data Structures&lt;Problem C&gt;

C - 秋实大哥与快餐店 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 朝为田舍郎,暮登天子堂.秋实大哥从小就怀抱有远大的理想,所以他开了一家快餐店. 秋实大哥根据菜的口感,给每一道菜一个唯一的CID,同时对于前来的客人,根据他们的口味喜好,秋实大哥会给每一个客人一个PID. 对于一个标号为PID的客人,他对标号为CID的菜的喜爱程度为PID∧CI

UESTC_Islands 2015 UESTC Training for Data Structures&lt;Problem J&gt;

J - Islands Time Limit: 30000/10000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status Deep in the Carribean, there is an island even stranger than the Monkey Island, dwelled by Horatio Torquemada Marley. Not only it has a re

UESTC_Sliding Window 2015 UESTC Training for Data Structures&lt;Problem K&gt;

K - Sliding Window Time Limit: 18000/6000MS (Java/Others)     Memory Limit: 131072/131072KB (Java/Others) Submit Status An array of size n≤106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the

UESTC_秋实大哥打游戏 2015 UESTC Training for Data Structures&lt;Problem H&gt;

H - 秋实大哥打游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status ”也许人生就是游戏,你却执意耕耘着春秋.” —— 秋实大哥叹道. 秋实大哥是一个喜欢玩游戏的人,相较于其他种类的游戏,秋实大哥更喜欢自由开放的沙盒游戏,尤其是minecraft. 现在,秋实大哥发现了N个独立的小岛(编号1,2,3.....N),于是他要把这些小岛连起来. 每一次

UESTC_秋实大哥去打工 2015 UESTC Training for Data Structures&lt;Problem G&gt;

G - 秋实大哥去打工 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 天行健,君子以自强不息.地势坤,君子以厚德载物. 天天过节的秋实大哥又要过节了,于是他要给心爱的妹子买礼物.但由于最近秋实大哥手头拮据,身为一个男人,他决定去打工! 秋实大哥来到一家广告公司.现在有n块矩形墙从左至右紧密排列,每一块高为Hi,宽为Wi. 公司要求秋实大哥找出一块最

UESTC_秋实大哥与家 2015 UESTC Training for Data Structures&lt;Problem E&gt;

E - 秋实大哥与家 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 秋实大哥是一个顾家的男人,他认为人生就是旅途,不管我们漂到哪,最终还是会回到温暖的地方——家. 所以他买了很多家具. 秋实大哥的家可以看成一个W×H的矩阵,每一件家具可以看成一个矩形,他们放置在秋实大哥的家里,相互之间没有重叠. 现在秋实大哥购置了一个新的大小为1×M的家具,秋实大

UESTC_秋实大哥下棋 2015 UESTC Training for Data Structures&lt;Problem I&gt;

I - 秋实大哥下棋 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 胜负胸中料已明,又从堂上出奇兵.秋实大哥是一个下棋好手,独孤求败的他觉得下棋已经无法满足他了,他开始研究一种新的玩法. 在一个n×m的棋盘上,放置了k个车,并且他在棋盘上标出了q个矩形,表示矩形内部是战略要地. 秋实大哥要求一个矩形内的每一个格子,都至少能被一辆在矩形内的车攻击到,

UESTC_秋实大哥与花 2015 UESTC Training for Data Structures&lt;Problem B&gt;

B - 秋实大哥与花 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 秋实大哥是一个儒雅之人,昼听笙歌夜醉眠,若非月下即花前. 所以秋实大哥精心照料了很多花朵.现在所有的花朵排成了一行,每朵花有一个愉悦值. 秋实大哥每天要对着某一段连续的花朵歌唱,然后这些花朵的愉悦值都会增加一个相同的值v(v可能为负). 同时他想知道每次他唱完歌后这一段连续的花朵的