一元逆序對問題:poj-2299
此題本質是乙個求逆序對問題,對於乙個無序數列,我們按照其順序依次輸入,並在每次輸入時通過樹狀陣列對已輸入數列在其後方的序列進行個數求和,即可得到逆序數(先輸入卻比他大,在其後方)
需要注意的是數列的值可能相差較大,如果按值更新樹狀陣列會浪費很多空間,對於此問題我們可以利用資料的離散化來處理
#include #include #include #define maxsize 500002
using namespace std; //使用命名空間std
struct node
;bool cmp(node a, node b)
int main()
//原陣列初始化完成
sort(arry + 1, arry + n + 1, cmp); //按數值從小到大排序
for (i = 1;i <= n;i++) //按之前的元素下標進行順序復原
aa[arry[i].va] = i;
//對應陣列離散化完成
//樹狀陣列求逆序數
memset(val, 0, sizeof(val)); //樹狀陣列初始化
for (i = 1;i <= n;i++)
cout << ans << endl;
} return 0;
}int lowbit(int x)
void update(int val, int i, int cal,int arry_num)
int sum_pre(int val,int i)
int sum_between(int val,int pre, int last)
接下來我們來看一道樹狀陣列求逆序對的變形題:
二元逆序對問題:poj-3067
題意:日本有n個城市在東邊,從北至南編號為1 2 3,,,n,m個城市在西邊,從北至南編號為1 2 ,,,,m,k條高速公路將被建造
高速公路的一端在西邊,一端在東邊
輸入有多組樣例,
每組樣例第一行為
n m k
接下來有k行,分別為高速公路的端點
求高速公路的交點有多少個,不包括以城市為相交點
解決方法:
對ax,ay和bx,by兩條高速公路,有相交點必須(ax-bx)*(ay-by)<0(本質仍是求逆序對)
做法:先對這些線段做雙關鍵字排序,以x為主關鍵字公升序排列,x相同時再以y為次關鍵字公升序排列,再逐一插入這些線段,求出在它之前插入的線段中y大於當前線段的y的線段數目,把它累加到答案中,最終就可以得出答案。因為我們知道,如果兩條線段有交點,那麼必有一條線段的x小於另一條線段的x,而y大於另一條線段的y,又因為我們已經對x做了排序,所以只用求出y大於當前線段的y的線段數目即可。另外,由於答案可能會很大,所以需要使用long long
#include #include #include #include #define maxsize 1005
using namespace std; //使用命名空間std
struct road
;road line[maxsize*maxsize]; //路
int main()
printf("test case %d: %lld\n", temp, num);
temp++;
} return 0;
}bool cmp(road a, road b)
int lowbit(int x)
//一維樹狀陣列
void update_1(int val, int i, int cal, int arry_num)
long long sum_pre_1(int val, int i)
long long sum_between_1(int val, int pre, int last)
樹狀陣列求逆序對
題目描述 給定乙個陣列a,它包含n個整數,分別是a 1 a 2 a n 如果存在下標i和j,使得 i j 且 a i a j 同時成立,則 i,j 就為乙個 逆序對 那麼a陣列總共有多少對不同的 逆序對 輸入格式 1247.in 第一行為n 1 n 100000 接下來是n行,每行乙個長整型範圍內的...
樹狀陣列求逆序對
很久以前就學了樹狀陣列,也知道可以用來求逆序對,然而一直沒弄明白他是怎麼實現的 可能當時沒搞清楚逆序對是什麼吧。逆序對就是如果i j a i a j 這兩個就算一對逆序對,簡單來說,所有逆序對的個數和就是找每乙個數的前面有幾個比他的大的數,他們加起來的和就是逆序對的總數。知道什麼是逆序對後就好辦了,...
逆序對(樹狀陣列 歸併)
題目描述 貓貓tom和小老鼠jerry最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,tom老貓查閱到乙個人類稱之為 逆序對 的東西,這東西是這樣定義的 對於給定的一段正整數序列,逆序對就是序列中i小於j同時ai大於aj的有序對。知道這概念後,他們...