HDU 4776 Ants tire 優先佇列

2021-06-23 06:42:06 字數 1767 閱讀 4959

【題目大意】

有一棵樹,樹上一條簡單路徑(u,v)的價值定義為這條路徑的所有邊的異或和。求這些價值的第k大。

【思路】

如果我們統計根到節點u,路徑的異或和為a[u],顯然,路徑(u,v)的價值為a[u]^a[v]。問題變為了從n個數中選兩個不同的數,求異或,找第k大。因為k其實不是很大,我們可以考慮將1-max(k)的價值都找出來。用a建立tire樹,首先列舉路徑的左端點,通過tire找到乙個右端點,使得其異或值最大。把這些數加入優先佇列,顯然,這些數中,最大的那個,就是第一大的價值。然後把這個價值刪掉,通過原來的左端點,再找乙個右端點,使其異或值變成次大,並把這個值加入優先佇列。這個時候,佇列中最大的元素是第二大的價值。這樣一直找下去,就能把所有k都找到。

#pragma comment(linker, "/stack:102400000,102400000")

#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define mp(x,y) make_pair((x),(y))

#define pb(x) push_back(x)

typedef __int64 ll;

//typedef unsigned __int64 ull;

/* ****************** */

const ll inf = 1ll<<55;

const double inff = 1e100;

const double eps = 1e-8;

const ll mod = 10000000007ll;

const int nn = 100010;

const int mm = 5000010;

/* ****************** */

const int limit = 59;

struct g

e[nn*2];

int p[nn], t;

struct node

bool operator<(const node &tt)const

};ll a[nn];

struct tire

}tire[nn*60];

struct q

}q[nn];

ll anss[nn];

void add(int u,int v,ll w)

void dfs(int u,int fa)

}void tire_insert(ll val,int root,int &tire_cnt)

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

j = 1;

memset(anss, -1, sizeof(anss));

for(i = 1; i <= (ll)n*(n-1) && j <= m ; i ++)

if(ix.num > 1)

else

}for(i = 1; i <= m; i ++)

printf("%i64d\n", anss[i]);

}int main()

a[1] = 0;

dfs(1,-1);

scanf("%d", &m);

for(i = 1; i <= m; i ++)

sort(q+1,q+1+m);

solve(n, m);

}return 0;

}

HDU 2829 Lawrence dp 斜率優化

題意 一段直線上有n個點,每個點有乙隻價值,一條鐵路的價值等於每兩個點 可以直接或者間接相連,就是聯通路上是否有炸彈把路給炸了 積的和 思路 斜率優化 dp i j 為前i個點,炸j個線段能破壞的最大值 沒優化前的狀態轉移方程為dp i x max x 1 設計算點i時,j比k的值優,dp k x ...

hdu5976 Detachment 逆元 優化

傳送門 題意 給定乙個數x,我們可以把這個數分解成乙個乙個的小的數字a1,a2,a3 定義s a1 a2 a3 問如何分解x使得s最大,並且不能有重複的數字 思路 分解成數量多的小的數字,比分解成數量少的大的數字的乘積更大,這一點我不知道怎麼證明 並且由基本不等式我們可以知道,相等和的兩個數,越接近...

hdu2639 01揹包k優解)

沒怎麼理解題意,題意 有n件物品,揹包體積為v,給出一行價值和一行花費,求第k優解,每個物品只能取一次。思路 不考慮k優解,顯然是個簡單的01揹包,1維的陣列足夠表示。即便要求k優解,在k 30的條件下,此題再加1維也沒什麼好說的,用dp j k 表示揹包體積為j時的k優解,一開始不知道怎麼轉移,原...