日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Rain in ACStar HDU-3340】

發(fā)布時間:2025/3/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Rain in ACStar HDU-3340】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

·你正從AC星球返回,天又下起凸包雨,只好到線段樹下躲雨。

·英文題,述大意:

????? 一個豎直平面的美麗天空,會下凸包雨。凸包雨指的是邊數(shù)為3~6的多邊形,并且每一個它都遵守一個神奇定律,那就是自己不會有兩個橫坐標相同的點(即每個凸包自己的頂點不會出現(xiàn)在一條垂直于x軸的直線上)。現(xiàn)在有Q個操作:第一種是放置一個凸包雨(即輸入其邊數(shù),并從其橫坐標最小點開始順時針讀入頂點坐標[x,y<=1000000000]);第二種是詢問,即讀入l,r來詢問我們橫坐標在[l,r]之間的雨滴的面積總和(被切開的雨也算),也就是求[l,r]的凸包總面積。(Q<=25000)

·分析:

????? 凸包雨很多,詢問很多。我們需要使用數(shù)據(jù)結(jié)構加以維護。請選擇一款你是喜愛的數(shù)據(jù)結(jié)構滿足以下條件:①你喜歡②可以維護區(qū)間的凸包面積!

但問題是這是一個二維的問題,我們需要加以轉(zhuǎn)化,目的是使每個凸包的面積便于使用某種美妙的數(shù)據(jù)結(jié)構維護。

????? 嘗試將計算形形色色的凸包的方法單一化,我們從一個簡單可愛的四邊形入手:現(xiàn)在知道其頂點坐標,怎么求面積?

??????????????????????????????????????????????

?

?????? 我們探索面積求法的目的需要再次說明:使得對各種多邊形面積計算的方法單一化。從坐標的角度思考,我們可以想到作差法(這很常用),但是選擇它的一個主要原因是,可以將任意多邊形分解為幾個梯形的面積加加減減的美好結(jié)果(當然,矩形,三角形這里可看做特殊的梯形,因為它們的面積計算同樣滿足:S=(l1+l2)*h/2)。即:將面積計算方法單一化。如圖:

?

?

??????????? 如美麗的圖:我們發(fā)現(xiàn),四邊形面積就可以使用兩個綠色梯形的面積減去兩個黃色梯形的面積。很開心發(fā)現(xiàn)這個結(jié)論。但是我們需要進一步推廣,獲得一個普遍的計算方式。我們需要快速確定什么該減什么時候該加。順著輸入的順序(從最左邊點的逆時針)如圖:

?????????????????????????????

??????? 按照讀入順序,我們根據(jù)上文結(jié)論,可以知道,這個多邊形的面積是上頂點為(5 1)(4 5)的梯形面積和減去上頂點為(1 2)(2 3)(3 4)的梯形面積。接著你就驚奇地發(fā)現(xiàn),有規(guī)律:按照逆時針順序,對于一個點a,如果它的上一個點的橫坐標比它小,那么以它倆為上頂點的梯形面積就要減去;反之,如果是橫坐標大,則這個梯形的面積就要加上(想一想,很容易)。所以在讀入后就可以按照這個方法了。

?????? 怎么操作?現(xiàn)在我們獲得了求梯形面積的方法,基于相鄰每個點的坐標。這個時候就是數(shù)據(jù)結(jié)構了。對于一個梯形,就用小學的面積公式,意思說我們只需要維護上下底的長度(即兩個點的縱坐標)。如個圖:

???????????????????????????

?????? 你決定了,要使用線段樹啦啦。實際上寫代碼時候,我們可以引入一個思想和一個變量來使得CODING更加美妙。思想是我們可以看做是線段樹維護等差數(shù)列(注意維護等差數(shù)列的基本思路:維護左右端點和公差)。方法是引入公差,即凸包那一條邊的斜率,這樣便于計算在線段樹PushDown的時候的中間數(shù)。

??????? 線段樹的特別的參數(shù)有:A(左端點加的值,即等差數(shù)列第一項),B(左端點加的值),ratio(斜率),它們對應的Lazy數(shù)組是:a[],b[],G[],另外,需要維護一個Sum[]表示當前區(qū)間的面積和(面積加加減減)。例子在這里:(例如向區(qū)間[1,4]插入等差數(shù)列{1,2,3,4})

?????? 最后是一些美妙的提醒和細節(jié)處理:

①注意在Lazy下放和線段樹區(qū)間分裂時都可能會有取中項的操作

②離散化詢問,以及點的橫坐標(所以在計算的時候一定要調(diào)用原長)

③本題的一個線段樹葉子結(jié)點是l+1==r表示一段小區(qū)間。

④在PushDown時和update到達指定區(qū)間時都需要計算Sum(即Sum[u]+=)

????? 剩下的都在代碼里面,無比美妙。

?

1 #define D double 2 #define lch u<<1 3 #include<stdio.h> 4 #define rch u<<1|1 5 #define M (l+r>>1) 6 #include<algorithm> 7 #define Up Sum[u]=Sum[lch]+Sum[rch] 8 #define go(i,a,b) for(int i=a;i<=b;i++) 9 #define Rar(a) a=lower_bound(T+1,T+n+1,a)-T 10 using namespace std; 11 const int N=250003;char c[N]; 12 int C,m,t,tt,kk,k,n,len[N],T[N],I,J; 13 D A[N*4],B[N*4],Sum[N*4],G[N*4],ratio,ans; 14 struct Q{int l,r;}q[N];struct P{int x,y;}p[N][7]; 15 D Cal(D a,int s,D rate){return 1.0*a+1.0*s*rate;} 16 void build(int u,int l,int r) 17 { 18 A[u]=B[u]=Sum[u]=G[u]=0;if(l+1==r)return; 19 build(lch,l,M);build(rch,M,r); 20 } 21 void Down(int u,int l,int r) 22 { 23 G[lch]+=G[u],G[rch]+=G[u];A[lch]+=A[u];B[rch]+=B[u]; 24 D Z=Cal(A[u],T[M]-T[l],G[u]); 25 Sum[lch]+=1.0*(A[u]+Z)*(T[M]-T[l])/2; 26 Sum[rch]+=1.0*(Z+B[u])*(T[r]-T[M])/2; 27 B[lch]+=Z,A[rch]+=Z,A[u]=B[u]=G[u]=0; 28 } 29 void update(int u,int l,int r,int L,int R,D a,D b) 30 { 31 if(L<=l&&r<=R){A[u]+=a;B[u]+=b;G[u]+=ratio; 32 Sum[u]+=1.0*(a+b)*(T[r]-T[l])/2;return;}Down(u,l,r); 33 if(R<=M)update(lch,l,M,L,R,a,b); 34 else if(L>=M)update(rch,M,r,L,R,a,b); 35 else{D Z=Cal(a,T[M]-T[L],ratio); 36 update(lch,l,M,L,M,a,Z);update(rch,M,r,M,R,Z,b);}Up; 37 } 38 void query(int u,int l,int r,int L,int R) 39 { 40 if(L<=l&&r<=R){ans+=Sum[u];return;};Down(u,l,r); 41 if(L<M)query(lch,l,M,L,R); 42 if(R>M)query(rch,M,r,L,R); 43 } 44 int main(){scanf("%d",&C);while(C--&&scanf("%d",&m)) 45 { 46 n=k=t=tt=kk=0; 47 go(i,1,m){scanf(" %c",&c[i]); 48 if(c[i]=='R'&&scanf("%d",&len[++t])) 49 go(j,1,len[t])scanf("%d%d",&p[t][j].x,&p[t][j].y),T[++n]=p[t][j].x; 50 if(c[i]=='Q'&&scanf("%d%d",&q[k].l,&q[++k].r))T[++n]=q[k].l,T[++n]=q[k].r;} 51 52 sort(T+1,T+n+1);n=unique(T+1,T+n+1)-T-1; 53 go(i,1,k)Rar(q[i].l),Rar(q[i].r);build(1,1,n); 54 go(i,1,t)go(j,1,len[i])Rar(p[i][j].x); 55 56 go(i,1,m)if(c[i]=='R'&&++tt)go(j,1,len[tt]) 57 { 58 I=j,J=j!=len[tt]?j+1:1; 59 int x1=p[tt][I].x,y1=p[tt][I].y,x2=p[tt][J].x,y2=p[tt][J].y; 60 if(x1<x2)y1*=-1,y2*=-1;else swap(x1,x2),swap(y1,y2); 61 ratio=1.0*(y2-y1)/(T[x2]-T[x1]);update(1,1,n,x1,x2,y1,y2); 62 } 63 else ++kk,ans=0,query(1,1,n,q[kk].l,q[kk].r),printf("%.3f\n",ans); 64 }return 0;}//Paul_Guderian

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

人們在卑微地倒立,可樓群卻都高高在上,

這是不能接受的事實,真實得就像夢境一樣?!舴濉恫荒芙邮艿氖聦崱?/strong>

轉(zhuǎn)載于:https://www.cnblogs.com/Paul-Guderian/p/7226112.html

總結(jié)

以上是生活随笔為你收集整理的【Rain in ACStar HDU-3340】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。