POJ 3928 Ping pong(樹狀陣列)

2021-07-22 12:46:57 字數 1789 閱讀 5887

題意:每個人都有乙個獨特的排名(數字大小)與獨特的位置(從前往後一條線上),求滿足排名在兩者之間並且位置也在兩者之間的三元組的個數

思路:單去列舉哪些數字在兩者之間只能用o(n^3)時間太高,但是可以轉變思想。我們可以轉化為對於每個數字a,求出後面比當前數a大的每個數b,再求出數b後面比當前數b大的數字c的個數,接著對於每個a對應的每個b中c的個數之和就是一半結果,當然還有比他小的是另一半求法類似。其實就是樹狀陣列求逆序數第一次求出每個b,接著再用b求出c,這樣求兩次就好

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define eps 1e-8

/*注意可能會有輸出-0.000*/

#define sgn(x) (x<-eps? -1 :x//x為兩個浮點數差的比較,注意返回整型

#define cvs(x) (x > 0.0 ? x+eps : x-eps)//浮點數轉化

#define zero(x) (((x)>0?(x):-(x))//判斷是否等於0

#define mul(a,b) (a<#define dir(a,b) (a>>b)

typedef

long

long ll;

typedef

unsigned

long

long ull;

const

int inf=1

<<28;

const

double pi=acos(-1.0);

const

int mod=1e9+7;

const

int max=20010;

struct node

num[max];

int n;

ll bit[max];

int lowbit(int x)

void add(int x,int y)

return;

}ll sum(int x)

return sum;

}ll manx(int n,int *pop,int *ivsn,int *ivsn2,int hh)

return manx;

}int pop[max],ivsn[max],ivsn2[max];

bool cmp(struct node p1,struct node p2)

sort(num+1,num+n+1,cmp);

for(int i=1;i<=n;i++)

pop[num[i].pos]=i;//離散化

manx(n,pop,ivsn,ivsn2,1);//找出pop陣列每個數後面比當前大的每個位置的ivsn2陣列值的總和

ans+=manx(n,pop,ivsn2,ivsn,1);

for(int i=1;i<=n;i++)

ivsn2[i]=1;

manx(n,pop,ivsn,ivsn2,0);//找出pop陣列每個數後面比當前小的每個位置的ivsn2陣列值的總和

ans+=manx(n,pop,ivsn2,ivsn,0);

printf("%i64d\n",ans);

}return

0;}

poj 3928 Ping pong 樹狀陣列

以裁判為基礎計算,每個運動員的技術水平都是不變的,他們對應的編號也是不變的,首先將它們按技術水平排序,但對應的編碼不變 如 技術 9 1 2 5 4 編碼 1 2 3 4 5 排序後 1 2 4 5 9 編碼 2 3 5 4 1 再找他們每個人的左邊 比他小的 有多少人,右邊 即比他大的 有多少人,...

POJ3928 Ping pong 樹狀陣列

題目中只n個人,每個人有乙個id和乙個技能值,一場比賽需要兩個選手和乙個裁判,只有當裁判的id和技能值都在兩個選手之間的時候才能進行一場比賽,現在問一共能組織多少場比賽。這道題目是用 樹狀陣列統計問題。首先我們要對技能值從小到大排序,然後利用每乙個選手的id對樹狀陣列進行維護。每次維護乙個id之前先...

POJ 3928 Ping pong 樹狀陣列

樹狀陣列的運用 具體就是列舉每個裁判,左邊比裁判小的個數乘以右邊比裁判大的個數,以及左邊比裁判大的個數乘以右邊小的個數,總和即為結果 id sdj22251 prog calfflac lang c include include include include include include in...