這道題似乎是vijos上能找到的最簡單的樹狀陣列題了。
原來,我有乙個錯誤的思想,我的設計是維護兩個樹狀陣列,乙個是橫座標,乙個是縱座標,然後讀入每個點的座標,扔進對應的樹狀陣列內,然後計算時,只要以當前點的座標為末點求字首和,在兩個字首和中取最小的乙個即可。
但是這個想法很明顯有錯誤比如如圖的狀況:
此時,在計算1點時,兩個的字首和均為1,但事實上,1點能保護的點為0個。
那麼我們應該怎麼去解這道題呢?
其實也很簡單,我們只維護乙個樹狀陣列,
首先我們先把點排序,以y為主關鍵字,x為副關鍵字,從小到大排序。
然後我們從排序後的第乙個點開始計算,我們求一下以當前點的x座標為末點的字首和,這就是當前保護的數量,然後在把當前的這個x座標扔進樹狀陣列。
為什麼這麼做是正確的?
這很簡單,求x的字首和,保證得出的都是小於x的點,而按y的順序列舉,橫座標大於等於當前y的點還沒放入(我們是計算完才放入的),這樣就保證了我們得出的數是我們期望求的。
**如下:
#include
#include
#include
using
namespace
std;
int xvis[32002];
int n;
struct point;
int cmp(point a,point b)
void add(int x,int p)
}int sum(int x)
return ans;
}int vis[15001];
int main()
memset(vis,0,sizeof(vis));
sort(pp,pp+n,cmp);
for(int i=0;iint ans=sum(pp[i].x);
add(pp[i].x,1);
vis[ans]++;
}for(int i=0;iprintf("%d",vis[i]);
if(i!=n-1)
}return
0;}
弱題(迴圈矩陣1)
時間限制 1 sec 記憶體限制 128 mb 有m個球,一開始每個球均有乙個初始標號,標號範圍為1 n且為整數,標號為i的球有ai個,並保證 ai m。每次操作等概率取出乙個球 即取出每個球的概率均為1 m 若這個球標號為k k n 則將它重新標號為k 1 若這個球標號為n,則將其重標號為1。取出...
弱雞演算法結構leetcode刷題(1)陣列
原題 1.給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。你可以假設每種輸入只會對應乙個答案。但是,你不能重複利用這個陣列中同樣的元素。class solution def twosum self,nums list int...
樹狀陣列題 1
給你乙個 n n 的矩陣,不用算矩陣乘法,但是每次詢問乙個子矩形的第 k 小數。第一行兩個數 n,q 表示矩陣大小和詢問組數 接下來 n 行 n 列一共 n n 個數,表示這個矩陣 再接下來 q 行每行5個數描述乙個詢問 x1,y1,x2,y2,k 表示找到以 x1,y1 為左上角 以 x2,y2 ...