【NOIP2013模拟】小喵喵的新家
Description
小喵喵和小聰聰從小就是好朋友 ,他們經常在一起玩耍 。如今小喵已經厭倦了自己居住的環境,想請小聰聰為她建一個新家。
小喵喵天生多才多藝,對多種樂器頗有研究。對于生活中常見的圖形,她對圓形很感興趣,因此小聰聰決定為她建一個圓形的新家。
我們設新家在一個平面直角坐標系上,其中新家的圓心為平面直角坐標系的原點。
小聰聰有一把神奇的剪刀,他定義了一個值m,以等分 [?pi,pi]弧度 (詳見樣例)。他還有一支神奇的畫筆,將進行 n次“鋪地毯”操作。對于第i 次“鋪地毯”操作,他將設定一個半徑ri,起始位置si,終止位置ti ,然后從圓心角pi*si/m到圓心角pi*ti/m這部分區域逆時針鋪上一個扇形地毯。
小喵喵想到了一個奇怪的問題,她想知道有多大面積被至少鋪過k次地毯。 這個問題一下就難倒了聰明的小聰聰。 現在小聰聰求助于你,你能幫他解決這個問題嗎?為了方便表達 ,設答案的值為T,你只需要輸出 T×2m/pi的值即可 。
Input
第一行是三個整數 n,m,k,含義 如題目描述中所述。
接下來n行, 每行描述一次鋪地毯操作 。第i行有三個整數r,si,ti,含義 如 題目描述中所述。
Output
輸出 一個整數 表示T×2m/pi的值。
Sample Input
3 8 2
1 -8 8
3 -7 3
5 -5 5
Sample Output
76
Data Constraint
Hint
.
.
.
.
.
分析
對于60%的做法:
前6個點,直接上暴力,別慫
對于后6個點,所有的半徑都是相同的,直接用差分約束思想,在扇形開始為1,結束為-1
做一遍前綴和,然后將大于等于k的區間的長度求出來,算面積
對于100%的做法:
扇形的面積:(所占的份數/2m)*πr^2
題目說:答案要乘一個2m/π
這樣一相乘 化簡:所占份數*r^2
就不用考慮精度問題啦!!!(出題人好評)
現在就要求出所有被覆蓋大于等于k的面積,半徑就是第k大的半徑
那一個部分中有什么半徑,我們怎么知道呢?
我們把圓拆成一條線段,端點就是圓圈上的各個等分點
把地毯的半徑視為高,連接起始點和終點,如果有橫跨線段中點的,把它看作兩個部分
設g[r]為半徑為r的數量
我們可以從-m掃過去,碰到起始點的時候就把其對應的g[r]+1,碰到結束點的時候就把其對應的g[r]-1(也就類似與差分約束)
現在就要求第k大值
用線段樹維護就好了
.
.
.
.
.
程序:
#include<iostream> using namespace std; long long ans; int n,m,tj,r,s,k,t,p[500001],to[500001],head[200001],w[200001];struct edge { int a,b,c; }e[500010];void cr(int x,int y) { e[++tj].a=x; e[tj].b=y; e[tj].c=r; }void work(int l,int r,int d,int a,int b) {if (l==r) {p[d]+=b;return;}int mid=(l+r)/2;if (a<=mid) work(l,mid,d*2,a,b); else work(mid+1,r,d*2+1,a,b);p[d]=p[d*2]+p[d*2+1]; }int abs(int x) { if (x>=0) return x; else return -x+100000; }int find(int l,int r,int x,int k) {if (l==r) {if (p[x]>=k) return l; else return 0;}int mid=(l+r)/2;if (p[x*2+1]>=k) return find(mid+1,r,x*2+1,k); else return find(l,mid,x*2,k-p[x*2+1]); } int main() {cin>>n>>m>>k;for (int i=1;i<=n;i++){cin>>r>>s>>t;if (s==-m||s==m) {cr(-m,1);cr(t,-1);} else{if (t==-m) t=m;if (t>=s) {cr(s,1);cr(t,-1);} else {cr(s,1);cr(m,-1);cr(-m,1);cr(t,-1);}}}for (int i=1;i<=tj;i++){int j=abs(e[i].a);if (!head[j]) head[j]=i; else to[w[j]]=i;w[j]=i;}for (int i=-m;i<=m-1;i++){for (int j=head[abs(i)];j!=0;j=to[j]) work(1,100000,1,e[j].c,e[j].b);long long a=find(1,100000,1,k);ans+=a*a;}cout<<ans;return 0; }轉載于:https://www.cnblogs.com/YYC-0304/p/9499914.html
總結
以上是生活随笔為你收集整理的【NOIP2013模拟】小喵喵的新家的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【NOIP2013模拟联考5】军训(tr
- 下一篇: Vijos 1197 - 费解的开关