樹狀陣列訓練題1 弱弱的戰壕(vijos1066)

2021-08-10 03:14:41 字數 1135 閱讀 5843

這道題似乎是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 ...