博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UESTC_Rain in ACStar 2015 UESTC Training for Data Structures<Problem L>
阅读量:5285 次
发布时间:2019-06-14

本文共 9238 字,大约阅读时间需要 30 分钟。

 

 

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
17Q 1 100R 410 10 11 10 13 11 12 11Q 10 11Q 1 100R 3100 20 120 20 110 30Q 1 100Q 12 120
0.0000.2501.0001.000100.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 
2 #include
3 #include
4 #include
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 else109 {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 else159 {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 set177 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 else199 {200 double k = getk(x1,y1,x2,y2); //添加正面积 201 updata(t2,t1,1,y2,y1,k);202 }203 }204 }205 else206 {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 }

 

 

转载于:https://www.cnblogs.com/Xiper/p/4470227.html

你可能感兴趣的文章
Linux下离线安装MySQL
查看>>
微信接口请求万能函数http_request
查看>>
一个项目最忌讳什么
查看>>
Linq to DataSet
查看>>
SQL SERVER 強制指定使用索引 -转载 只为学习
查看>>
2015最新百度搜索引擎(seo优化)排名算法
查看>>
ADSL 拨号实现
查看>>
第2章 线程安全性-加锁机制
查看>>
摆放与布局——普通流、浮动定位、绝对定位、表格
查看>>
理解线程池中线程的复用原理
查看>>
腾讯面试题
查看>>
mysql日志配置
查看>>
面向对象总结
查看>>
超市帐单系统
查看>>
The Django Book
查看>>
2-1 Restful中HTTP协议介绍
查看>>
mysql密码过期的修改方法(your password has expired)
查看>>
Luogu2881 排名的牛Ranking the Cows
查看>>
【原创】自己动手实现RPC服务调用框架
查看>>
WC.exe-软工作业(一)
查看>>