zoukankan      html  css  js  c++  java
  • 【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()
  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    《EffectiveJava中文第二版》 高清PDF下载
    《MoreEffectiveC++中文版》 pdf 下载
    《啊哈c语言》 高清 PDF 下载
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5190538.html
Copyright © 2011-2022 走看看