wyh的商機(
一天,你們wyh學長和你們zhl學長玩乙個遊戲,這個遊戲規則是這樣的
給你n個城市,保證這n個城市之間都只有一條道路可以到達。
有一件物品,在所有城市中都是一樣的,但是由於各個城市的經濟發展不同,導致每個城市對於這件物品銷售的**不同。
遊戲一共進行q輪。
每輪給你2個點s和t,其中s代表起點,t代表終點。
對於每乙個城市都可以選擇買這個物品,如果手裡有這個物品的話,也可以選擇賣掉這個物品,對於同乙個城市來說,買和賣的**是一樣的,每乙個城市只能買一件物品
從s-t只能進行一次買賣,現在,你們wyh學長和zhl學長都需要找到乙個方案,使得從起點走到終點的時候盈利最多,請你幫助幫助他們吧
每個測試檔案中都只有一組測試資料
輸入第一行乙個整數n(1<=n<=50000),代表有n個城市
第二行輸入n個數,代表每個城市對於這件物品的**wi(1<=wi<=50000)
接下來有n-1行,每行2個數a和b,代表a到b之間有一條路
接下來輸入乙個數q(1<=q<=50000)
接下來q行,每行2個數s和t
對於每組測試資料,輸出對應答案,如果從起點到終點不能盈利的話,輸出041
5321 3
3 23 4
91 2
1 31 4
2 32 1
2 43 1
3 23 442
2000
020對於乙個詢問u-v。我們把詢問分成u-lca和lca-v。
那麼最優值可以是:在u-lca進行買賣,在lca-v進行買賣.
在u-lca進行買在lca-v進行賣。
那麼我們維護三個東西:
\(up[i][j]:節點i到往上2^j個節點的樹鏈之間進行買賣能夠得到的最大利潤\)
\(down[i][j]:節點x往下2^j個節點到i的樹鏈之間進行買賣能夠得到的最大利潤\)
\(mx[i][j]:節點i到往上2^j個節點的樹鏈之間最大權值\)
\(mi[i][j]:節點i到往上2^j個節點的樹鏈之間最小權值\)
我們在樹上維護呢?
和上面一樣,就是要麼是在x-y進行買賣最大值,y-z買賣的最大值。或者在x-y買,在y-z進行賣。
\(up[x][j+1]=max(max(up[x][j], up[y][j]), mx[y][j]-mi[x][j])\)
down和up的區別是在z-y進行買, 在y-x賣。
\(up[x][j+1]=max(max(up[x][j], up[y][j]), mx[x][j]-mi[y][j])\)
mi和mx的維護就很簡單了。
我們處理查詢。對於一條鏈,我們每次只合併兩個區間,同樣的方法處理。
#include #define ll long long
using namespace std;
struct edge e[100000+10];
int head[50010], cut=0;
void addedge(int x, int y) ;
head[x]=cut;
}ll w[50010];
int f[50010][22], deep[50010];
ll mx[50010][22], mi[50010][22], up[50010][22], down[50010][22];
int n;
void dfs(int u, int fa, int d)
}}void init() else }}
}int lca(int x, int y)
}if(x==y)
return x;
for(int i=20; i>=0; i--)
}return f[x][0];
}ll getup(int x, int k, ll &mi_uf)
}return res;
}int main()
for(int i=1; i
init();
int q;
scanf("%d", &q);
while(q--)
}return 0;
}
樹鏈剖分 樹上倍增 線段樹 遙遠的國度
難點在於如何處理換根操作。我們可以分情況討論。假設當前根節點為roo troot root 詢問子樹為son son。son。然後就是比較模板的樹鏈剖分了。include define int long long using namespace std const int n 200000 int ...
樹上的簡單操作 樹鏈剖分
某神犇 樹鏈剖分什麼垃圾,能做的lct都能做,不能做的lct也能做 線段樹,都會線段樹了應該知道什麼是樹吧 現在考慮一棵樹,每個節點都有乙個點權,要求給x到y路徑上的點都加上k,這個問題可以用樹上差分很簡單地在o m n 的複雜度內解決。再考慮乙個問題,要求查詢樹上x到y這條路徑上的權值和,也可以先...
牛客 樹上子鏈(模擬樹的直徑,求最大子樹)
傳送門 昨天牛客比賽,最後8分鐘左右ac這道題,這題正解應該是樹形dp,無奈我樹形dp學的不好,最後想到樹的直徑,樹的直徑是樹的特有性質,雖然我也不太確定,然後就dfs 模擬樹的直徑,兩次dfs 求得路程中最大權值和,沒想到a了,有點小激動 模擬樹的直徑ac include.h using name...