/******************************************************************************************************************
尼瑪。。。神題。。。居然能卡RMQ的log2的。。。解法就是先用樹狀DP預處理整棵樹,得到每個節點距離其他節點的最大值,
這個時間複雜度是O(n),然後在得到的dp數組上做RMQ詢問,注意在詢問過程中,可以用一個隊列維護,只要保持整個隊列中極值之
差<=q即可,RMQ的預處理時間複雜度爲O(nlog n),詢問的時間複雜度爲O(mn),不加優化的話,TLE掉。。。然後尼瑪上網查
下優化居然是把RMQ的log2用數組代替掉。。。碉堡了。。。
******************************************************************************************************************/
#include <iostream>
#include <functional>
#include <algorithm>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <utility>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define LOWBIT(x) ( (x) & ( (x) ^ ( (x) - 1 ) ) )
#define CLR(x, k) memset((x), (k), sizeof(x))
#define CPY(t, s) memcpy((t), (s), sizeof(s))
#define SC(t, s) static_cast<t>(s)
#define LEN(s) static_cast<int>( strlen((s)) )
#define SZ(s) static_cast<int>( (s).size() )
typedef double LF;
//typedef long long LL; //GNU C++
//typedef unsigned long long ULL;
typedef __int64 LL; //Visual C++ 2010
typedef unsigned __int64 ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<double, double> PDD;
typedef map<int, int>::iterator MI;
typedef vector<int>::iterator VI;
typedef list<int>::iterator LI;
typedef set<int>::iterator SI;
template <typename T>
T sqa(const T &x)
{
return x * x;
}
template <typename T>
T gcd(T a, T b)
{
if (!a || !b)
{
return max(a, b);
}
T t;
while (t = a % b)
{
a = b;
b = t;
}
return b;
}
template <typename T>
T ext_gcd(T a, T b, T &x, T &y)
{
if (!b)
{
x = 1;
y = 0;
return a;
}
T d = ext_gcd(b, a % b, x, y);
T t = x;
x = y;
y = t - a / b * y;
return d;
}
template <typename T>
T invmod(T a, T p)
{
LL inv, y;
ext_gcd(a, p, inv, y);
inv < 0 ? inv += p : 0;
return inv;
}
const int INF_INT = 0x3f3f3f3f;
const LL INF_LL = 0x7fffffffffffffffLL; //15f
const double oo = 10e9;
const double eps = 10e-7;
const double PI = acos(-1.0);
#define ONLINE_JUDGE
const int MAXN = 50004;
int n, m;
struct Edges
{
int end;
int len, max_len;
int next;
}edges[MAXN << 1];
int ecnt, head[MAXN];
int dp[MAXN];
int bin[22], dpMI[MAXN][22], dpMX[MAXN][22];
bool hs[MAXN];
int lg2[MAXN];
int myLog2(const int &x)
{
int l = 0, r = 22, mid = (l + r) >> 1;
int res = 0;
while (l <= r)
{
mid = (l + r) >> 1;
if (bin[mid] <= x)
{
l = mid + 1;
res = mid;
}
else
{
r = mid - 1;
}
}
return res;
}
void preprocess()
{
bin[0] = 1;
for (int i = 1; i < 22; ++i)
{
bin[i] = bin[i - 1] << 1;
}
int ind = 0;
for (int i = 1; i < MAXN; ++i)
{
if (i < bin[ind + 1])
{
lg2[i] = ind;
}
else
{
lg2[i] = ++ind;
}
}
return ;
}
void inline add_edge(int u, int v, int c)
{
edges[ecnt].end = v;
edges[ecnt].len = c;
edges[ecnt].max_len = 0;
edges[ecnt].next = head[u];
head[u] = ecnt++;
return ;
}
void dfs_root(const int &u)
{
hs[u] = true;
int v, c;
for (int i = head[u]; i != -1; i = edges[i].next)
{
v = edges[i].end;
c = edges[i].len;
if ( hs[v] )
{
continue ;
}
dfs_root(v);
edges[i].max_len = dp[v] + edges[i].len;
dp[u] = max( dp[u], dp[v] + edges[i].len );
}
return ;
}
void dfs_leaf(const int &t, const int &u)
{
if ( hs[u] )
{
return ;
}
hs[u] = true;
int v;
int mx = 0;
for (int i = head[t]; i != -1; i = edges[i].next)
{
v = edges[i].end;
if (u == v)
{
continue ;
}
mx = max( mx, edges[i].max_len );
}
for (int i = head[u]; i != -1; i = edges[i].next)
{
v = edges[i].end;
if (t == v)
{
edges[i].max_len = edges[i].len + mx;
break ;
}
}
for (int i = head[u]; i != -1; i = edges[i].next)
{
dp[u] = max( dp[u], edges[i].max_len );
}
for (int i = head[u]; i != -1; i = edges[i].next)
{
v = edges[i].end;
if ( hs[v] )
{
continue ;
}
dfs_leaf(u, v);
}
return ;
}
void initST()
{
for (int i = 1; i <= n; ++i)
{
dpMI[i][0] = dpMX[i][0] = dp[i];
}
int k = lg2[n];
for (int j = 1; j <= k; ++j)
{
for (int i = 1; i + bin[j] - 1 <= n; ++i)
{
dpMI[i][j] = min( dpMI[i][j - 1], dpMI[ i + bin[j - 1] ][j - 1] );
dpMX[i][j] = max( dpMX[i][j - 1], dpMX[ i + bin[j - 1] ][j - 1] );
}
}
return ;
}
int queryST(int l, int r)
{
int k = lg2[r - l + 1];
return max( dpMX[l][k], dpMX[r - bin[k] + 1][k] ) -
min( dpMI[l][k], dpMI[r - bin[k] + 1][k]);
}
int search(const int &q)
{
int l = 1, r = 1;
int res = 0;
while (r <= n)
{
if (queryST(l, r) > q)
{
break ;
}
++r;
}
--r;
res = r - l + 1;
while (r <= n)
{
if (queryST(l, r) <= q)
{
res = max(res, r - l + 1);
++r;
}
else
{
++l;
}
}
return res;
}
void ace()
{
const int &root = 1;
int u, v, c;
int q;
while (scanf("%d %d", &n, &m), n || m)
{
ecnt = 0;
CLR(head, -1);
for (int i = 0; i < n - 1; ++i)
{
scanf("%d %d %d", &u, &v, &c);
add_edge(u, v, c);
add_edge(v, u, c);
}
CLR(hs, false);
CLR(dp, 0);
dfs_root(1);
CLR(hs, false);
for (int i = head[root]; i != -1; i = edges[i].next)
{
u = edges[i].end;
dfs_leaf(root, u);
}
initST();
while (m--)
{
scanf("%d", &q);
printf("%d\n", search(q));
}
}
return ;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
preprocess();
ace();
return 0;
}
HDU 4123 樹狀DP+RMQ
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.