【HDOJ】4729 An Easy Problem for Elfness

其实是求树上的路径间的数据第K大的题目。
果断主席树 + LCA。
初始流量是这条路径上的最小值。
若a<=b,显然直接为s->t建立pipe可以使流量最优;
否则,对【0, 10**4】二分得到boundry,使得boundry * n_edge - sum_edge <= k/b, 或者建立s->t,然后不断extend s->t。

  1 /* 4729 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 // #define lson            l, mid, rt<<1
 41 // #define rson            mid+1, r, rt<<1|1
 42 
 43 typedef struct {
 44     int v, c, nxt;
 45 } edge_t;
 46 
 47 const int maxn = 1e5+5;
 48 const int m = 10005;
 49 const int maxm = maxn * 20;
 50 int T[maxn];
 51 int lson[maxm], rson[maxm], c[maxm], sum[maxm];
 52 int head[maxn], l;
 53 edge_t E[maxn<<1];
 54 int tot, n, q;
 55 int beg[maxn];
 56 int V[maxn<<1], D[maxn<<1], top;
 57 int dp[18][maxn<<1];
 58 
 59 void init() {
 60     memset(head, -1, sizeof(head));
 61     l = top = 0;
 62     tot = 1;
 63 }
 64 
 65 int Build(int l, int r) {
 66     int rt = tot++;
 67 
 68     c[rt] = sum[rt] = 0;
 69     if (l == r)
 70         return rt;
 71 
 72     int mid = (l + r) >> 1;
 73 
 74     lson[rt] = Build(l, mid);
 75     rson[rt] = Build(mid+1, r);
 76 
 77     return rt;
 78 }
 79 
 80 int Insert(int rt, int x, int val) {
 81     int nrt = tot++, ret = nrt;
 82     int l = 0, r = m - 1, mid;
 83 
 84     c[nrt] = c[rt] + 1;
 85     sum[nrt] = sum[rt] + val;
 86     while (l < r) {
 87         mid = (l + r) >> 1;
 88         if (x <= mid) {
 89             lson[nrt] = tot++;
 90             rson[nrt] = rson[rt];
 91             nrt = lson[nrt];
 92             rt = lson[rt];
 93             r = mid;
 94         } else {
 95             lson[nrt] = lson[rt];
 96             rson[nrt] = tot++;
 97             nrt = rson[nrt];
 98             rt = rson[rt];
 99             l = mid + 1;
100         }
101         c[nrt] = c[rt] + 1;
102         sum[nrt] = sum[rt] + val;
103     }
104 
105     return ret;
106 }
107 
108 int Query_kth(int urt, int vrt, int frt, int k) {
109     int l = 0, r = m - 1, mid;
110     int tmp;
111 
112     while (l < r) {
113         mid = (l + r) >> 1;
114         tmp = c[lson[urt]] + c[lson[vrt]] - (c[lson[frt]] << 1);
115         if (tmp >= k) {
116             urt = lson[urt];
117             vrt = lson[vrt];
118             frt = lson[frt];
119             r = mid;
120         } else {
121             k -= tmp;
122             urt = rson[urt];
123             vrt = rson[vrt];
124             frt = rson[frt];
125             l = mid + 1;
126         }
127     }
128 
129     return l;
130 }
131 
132 int Query_Bound(int urt, int vrt, int frt, int delta) {
133     int l = 0, r = m - 1, mid;
134     int cc = 0, csum = 0;
135     int tc, tsum;
136     int ans = 0, tmp;
137 
138     while (l < r) {
139         mid = (l + r) >> 1;
140         tc = c[lson[urt]] + c[lson[vrt]] - (c[lson[frt]] << 1);
141         tsum = sum[lson[urt]] + sum[lson[vrt]] - (sum[lson[frt]] << 1);
142         tmp = mid*(tc+cc)-(tsum+csum);
143         if (tmp <= delta)
144             ans = max(ans, mid);
145         if (mid*(tc+cc)-(tsum+csum) >= delta) {
146             urt = lson[urt];
147             vrt = lson[vrt];
148             frt = lson[frt];
149             r = mid;
150         } else {
151             urt = rson[urt];
152             vrt = rson[vrt];
153             frt = rson[frt];
154             cc += tc;
155             csum += tsum;
156             l = mid + 1;
157         }
158     }
159 
160     return ans;
161 }
162 
163 void addEdge(int u, int v, int c) {
164     E[l].v = v;
165     E[l].c = c;
166     E[l].nxt = head[u];
167     head[u] = l++;
168 
169     E[l].v = u;
170     E[l].c = c;
171     E[l].nxt = head[v];
172     head[v] = l++;
173 }
174 
175 void dfs(int u, int fa, int dep) {
176     int v, k;
177 
178     V[++top] = u;
179     D[top] = dep;
180     beg[u] = top;
181 
182     for (k=head[u]; k!=-1; k=E[k].nxt) {
183         v = E[k].v;
184         if (v == fa)
185             continue;
186         T[v] = Insert(T[u], E[k].c, E[k].c);
187         dfs(v, u, dep+1);
188         V[++top] = u;
189         D[top] = dep;
190     }
191 }
192 
193 void Init_RMQ(int n) {
194     int i, j;
195 
196     for (i=1; i<=n; ++i)
197         dp[0][i] = i;
198     for (j=1; (1<<j)<=n; ++j)
199         for (i=1; i+(1<<j)-1<=n; ++i)
200             if (D[dp[j-1][i]] < D[dp[j-1][i+(1<<(j-1))]])
201                 dp[j][i] = dp[j-1][i];
202             else
203                 dp[j][i] = dp[j-1][i+(1<<(j-1))];
204 }
205 
206 int RMQ(int l, int r) {
207     if (l > r)
208         swap(l, r);
209 
210     int k = 0;
211 
212     while (1<<(k+1) <= r-l+1)
213         ++k;
214 
215     if (D[dp[k][l]] < D[dp[k][r-(1<<k)+1]])
216         return V[dp[k][l]];
217     else
218         return V[dp[k][r-(1<<k)+1]];
219 }
220 
221 void solve() {
222     T[1] = Build(0, m - 1);
223     dfs(1, 0, 0);
224     Init_RMQ(top);
225 
226     int u, v, k, a, b;
227     int lca;
228     int ans, tmp, org;
229 
230     while (q--) {
231         scanf("%d %d %d %d %d", &u, &v, &k, &a, &b);
232         lca = RMQ(beg[u], beg[v]);
233         org = Query_kth(T[u], T[v], T[lca], 1);
234         #ifndef ONLINE_JUDGE
235             // printf("f = %d
", lca);
236         #endif
237         if (a <= b) {
238             ans = org + k / a;
239         } else {
240             ans = org;
241             if (k >= a)
242                 ans += 1 + (k-a)/b;
243             tmp = Query_Bound(T[u], T[v], T[lca], k/b);
244             #ifndef ONLINE_JUDGE
245             // printf("org = %d, ans = %d, bound = %d
", org, ans, tmp);
246             #endif
247             ans = max(ans, tmp);
248         }
249         printf("%d
", ans);
250     }
251 }
252 
253 int main() {
254     ios::sync_with_stdio(false);
255     #ifndef ONLINE_JUDGE
256         freopen("data.in", "r", stdin);
257         freopen("data.out", "w", stdout);
258     #endif
259 
260     int t;
261     int u, v, c;
262 
263     scanf("%d", &t);
264     rep(tt, 1, t+1) {
265         init();
266         scanf("%d %d", &n, &q);
267         rep(i, 1, n) {
268             scanf("%d %d %d", &u, &v, &c);
269             addEdge(u, v, c);
270         }
271         printf("Case #%d:
", tt);
272         solve();
273     }
274 
275     #ifndef ONLINE_JUDGE
276         printf("time = %d.
", (int)clock());
277     #endif
278 
279     return 0;
280 }

数据发生器。

 1 from copy import deepcopy
 2 from random import randint, shuffle
 3 import shutil
 4 import string
 5 
 6 
 7 def GenDataIn():
 8     with open("data.in", "w") as fout:
 9         t = 10
10         bound = 10**4
11         fout.write("%d
" % (t))
12         for tt in xrange(t):
13             n = randint(100, 200)
14             q = randint(100, 200)
15             fout.write("%d %d
" % (n, q))
16             ust = [1]
17             vst = range(2, n+1)
18             for i in xrange(1, n):
19                 idx = randint(0, len(ust)-1)
20                 u = ust[idx]
21                 idx = randint(0, len(vst)-1)
22                 v = vst[idx]
23                 ust.append(v)
24                 vst.remove(v)
25                 c = randint(0, bound-1)
26                 fout.write("%d %d %d
" % (u, v, c))
27             for i in xrange(q):
28                 u = randint(1, n)
29                 while True:
30                     v = randint(1, n)
31                     if v!=u:
32                         break
33                 k = randint(0, bound)
34                 a = randint(1, bound)
35                 b = randint(1, bound)
36                 fout.write("%d %d %d %d %d
" % (u, v, k, a, b))
37                 
38                 
39 def MovDataIn():
40     desFileName = "F:eclipse_prjworkspacehdojdata.in"
41     shutil.copyfile("data.in", desFileName)
42 
43     
44 if __name__ == "__main__":
45     GenDataIn()
46     MovDataIn()
原文地址:https://www.cnblogs.com/bombe1013/p/5190538.html