[Vijos] 弱弱的戰壕

描述

永恆和mx正在玩一個即時戰略遊戲,名字嘛~~~~~~恕本人記性很差,忘了-_-b。spa

mx在他的基地附近創建了n個戰壕,每一個戰壕都是一個獨立的做戰單位,射程能夠達到無限(「mx不贏定了?!?」永恆ftING...@_@)。code

可是,戰壕有一個弱點,就是隻能攻擊它的左下方,說白了就是橫縱座標都不大於它的點(mx:「個人戰壕爲何這麼菜」ToT)。這樣,永恆就能夠從別的地方進攻摧毀戰壕,從而消滅mx的部隊。對象

戰壕都有一個保護範圍,同它的攻擊範圍同樣,它能夠保護處在它左下方的戰壕。全部處於它保護範圍的戰壕都叫作它的保護對象。這樣,永恆就必須找到mx的戰壕中保護對象最多的點,從而優先消滅它。blog

如今,因爲永恆沒有時間來計算,因此拜託你來完成這個任務:排序

給出這n個戰壕的座標xi、yi,要你求出保護對象個數爲0,1,2……n-1的戰壕的個數。遊戲

格式

輸入格式

第一行,一個正整數n(1<=n<=15000)
接下來n行,每行兩個數xi,yi,表明第i個點的座標
(1<=xi,yi<=32000)
注意:可能包含多重戰壕的狀況(即有數個點在同一座標)get

輸出格式

輸出n行,分別表明保護對象爲0,1,2……n-1的戰壕的個數。it

樣例1

樣例輸入1

5
1 1
5 1
7 1
3 3
5 5

樣例輸出1

1
2
1
1
0

限制

各點2s(算是寬限吧^_^)io

來源

URAL1028戰役版class

思路

sort以x爲第一關鍵字,y爲第二關鍵字排序,而後枚舉排好序的序列,以y爲關鍵字建造一棵線段樹,邊查詢邊增值便可;

代碼實現

 1 #include<cstdio>
 2 #include<algorithm>
 3 const int maxn=2e5;
 4 int n;
 5 int ans[maxn],t[maxn];
 6 struct nate{int x,y;}s[maxn];
 7 bool comp(nate a,nate b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
 8 void add(int k,int l,int r,int p){
 9     if(l==r){
10         t[k]++;
11         return;
12     }
13     int mid=l+r>>1,ls=k<<1,rs=ls|1;
14     if(p<=mid) add(ls,l,mid,p);
15     else add(rs,mid+1,r,p);
16     t[k]=t[ls]+t[rs];
17 }
18 int get(int k,int l,int r,int p){
19     if(r<=p) return t[k];
20     int mid=l+r>>1,ls=k<<1,rs=ls|1,ret=0;
21     ret+=get(ls,l,mid,p);
22     if(p>mid) ret+=get(rs,mid+1,r,p);
23     return ret;
24 }
25 int main(){
26     scanf("%d",&n);
27     for(int i=1;i<=n;i++) scanf("%d%d",&s[i].x,&s[i].y);
28     std::sort(s+1,s+n+1,comp);
29     for(int i=1;i<=n;i++){
30         ans[get(1,1,maxn,s[i].y)]++;
31         add(1,1,maxn,s[i].y);
32     }
33     for(int i=0;i<n;i++) printf("%d\n",ans[i]);
34     return 0;
35 }
相關文章
相關標籤/搜索