Happy King
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 434 Accepted Submission(s): 79
Problem Description
There are n
cities and n?1
roads in Byteland, and they form a tree. The cities are numbered
1
through n.
The population in i-th
city is pi.
Soda, the king of Byteland, wants to travel from a city
u
to another city v
along the shortest path. Soda would be happy if the difference between the maximum and minimum population among the cities passed is **no larger than**
D.
So, your task is to tell Soda how many different pairs
(u,v)
that can make him happy.
Input
There are multiple test cases. The first line of input contains an integer
T
(1≤T≤500),
indicating the number of test cases. For each test case:
The first line contains two integers n
and D
(1≤n≤100000,1≤D≤109).
The second line contains n
integers p1,p2,…,pn
(0≤pi≤109).
Each of the following n?1
lines describing roads contains two integers u,v
(1≤u,v≤n,u≠v)
meaning that there is a road connecting city u
and city v.
It is guaranteed that the total number of vertices in the input doesn‘t exceed
5×105.
Output
For each test case, output the number of different pairs that can make Soda happy.
Sample Input
1 3 3 1 2 3 1 2 2 3
Sample Output
6 Hint If you need a larger stack size, please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
题意,给出一个树,要求,其中,结点u - v的路径上最大值与最小值相差不超过k的个数。
与上一题是相同的做法。树点分冶
设分治中心为ggg,
我们只需要计算跨过ggg的答案,
其他的可以分治计算.
跨过根的可以容斥做, 没有限制的 - ∑端点落在同一颗子树上的. 上述两个过程是一样的, 于是只考虑没有限制的怎么做.
令xi,yix_i,y_ix?i??,y?i??为iii到ggg路径上的最大值和最小值.
我们按照xix_ix?i??排序,
然后枚举xix_ix?i??必选,
那么前面可选的xj,yj(j<i)x_j,
y_j (j < i)x?j??,y?j??(j<i)必须要满足xi?d≤xj,xi?d≤yjx_i
- d \le x_j, x_i - d \le y_jx?i???d≤x?j??,x?i???d≤y?j??,
由于xj≥yjx_j \ge y_jx?j??≥y?j??,
只需要考虑xi?d≤yjx_i -
d \le y_jx?i???d≤y?j??.
于是只要枚举xix_ix?i??然后用树状数组统计答案即可.
复杂度是O(nlog2n)O(n
\log^2 n)O(nlog?2??n).
#define N 100050 #define M 100005 #define maxn 205 #define MOD 1000000000000000007 struct TreeNum{ int a[N],n; //树状数组模板 void init(int nn){ n = nn + 1; for(int i = 0;i<=n + 1;i++) a[i] = 0; } int lowbit(int x) { return x & (-x); } void modify(int x,int add)//一维 { while(x<=n) { a[x]+=add; x+=lowbit(x); } } int get_sum(int x) { if(x < 0) return 0; if(x > n) x = n; int ret=0; while(x!=0) { ret+=a[x]; x-=lowbit(x); } return ret; } }; int T,n,m,k,u,v,l,center,all,num,nodes[N],dp[N],xx[N],yy[N],pri[N],mymap[N],no; __int64 ans; bool vis[N]; vector<pii> p[N]; vector<pii> depV; TreeNum mytree; void findRoot(int root,int fa){ nodes[root] = 1;dp[root] = 0; FI(p[root].size()){ int g = p[root][i].first; if(g != fa && !vis[g]){ findRoot(g,root); nodes[root] += nodes[g]; dp[root] = max(dp[root],nodes[g]); } } dp[root] = max(dp[root],all - nodes[root]); if(dp[root] < num){ num = dp[root];center = root; } } int getRoot(int root,int sn){ num = INF;all = sn;center = root; findRoot(root,-1); return center; } void getDp(int root,int fa){ nodes[root] = 1; depV.push_back(mp(xx[root],root)); mymap[no++] = yy[root]; FI(p[root].size()){ int g = p[root][i].first; if(g != fa && !vis[g]){ xx[g] = max(xx[root],pri[g]); yy[g] = min(yy[root],pri[g]); getDp(g,root); nodes[root] += nodes[g]; } } } int getIndex(int x){ return lower_bound(mymap,mymap + no,x) - mymap; } __int64 cal(int root,bool isfirst){ depV.clear();no = 0; if(isfirst) xx[root] = pri[root],yy[root] = pri[root]; getDp(root,-1); sort(depV.begin(),depV.end()); sort(mymap,mymap + no); no = unique(mymap,mymap + no) - mymap; __int64 sum = 0; mytree.init(no); for(int i = 0;i < depV.size();i++){ int xi = depV[i].first,yi = yy[depV[i].second]; if(xi - yi <= k ){ int goal = getIndex(xi - k); sum += (__int64)(mytree.get_sum(no + 1) - mytree.get_sum(goal)); } mytree.modify(getIndex(yi) + 1,1); } return sum; } void work(int root,int fa){ vis[root] = true; ans += cal(root,true); FI(p[root].size()){ int g = p[root][i].first; if(g != fa && !vis[g]){ ans -= cal(g,false); work(getRoot(g,nodes[g]),-1); } } } int main() { while(S(T)!=EOF) { while(T--){ S2(n,k); ans = 0; FI(n) p[i + 1].clear(),vis[i + 1] = false; FI(n) scan_d(pri[i+1]); FI(n-1){ S2(u,v); p[u].push_back(mp(v,1)); p[v].push_back(mp(u,1)); } work(getRoot(1,n),-1); printf("%I64d\n",ans * 2); } } return 0; }
Source
Recommend
hujie | We have carefully selected several similar problems for you: 5338 5337 5336 5335 5334
Statistic | Submit | Discuss
| Note
版权声明:本文为博主原创文章,未经博主允许不得转载。