Advertisement
FyanRu

Untitled

Jun 24th, 2024
465
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.63 KB | None | 0 0
  1. #include <algorithm>
  2. #include <array>
  3. #include <bitset>
  4. #include <cassert>
  5. #include <chrono>
  6. #include <complex>
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <deque>
  10. #include <iomanip>
  11. #include <iostream>
  12. #include <iterator>
  13. #include <list>
  14. #include <map>
  15. #include <memory>
  16. #include <numeric>
  17. #include <queue>
  18. #include <random>
  19. #include <set>
  20. #include <stack>
  21. #include <string>
  22. #include <tuple>
  23. #include <vector>
  24. using namespace std;
  25. using namespace std::chrono;
  26. #define all(x) begin(x), end(x)
  27. #define sz(x) (int) (x).size()
  28.  
  29. const int mxn = 1e5+1;
  30. const int inf = 1e9;
  31.  
  32. struct sparsemin {
  33.     vector<int> a;
  34.     int h;
  35.     vector<vector<int> > st;
  36.     sparsemin() {}
  37.     sparsemin(vector<int>& arr) : a(arr) {
  38.         h = log2(a.size()) + 1;
  39.         st.resize(h+1);
  40.         for (int i = 0; i < a.size(); i++) st[0].push_back(i);
  41.         for (int i = 1; i <= h; i++) {
  42.             for (int j = 0; j + (1<<i) <= arr.size(); j++) {
  43.                 if (a[st[i-1][j]] < a[st[i-1][j + (1<<(i-1))]]) {
  44.                     st[i].push_back(st[i-1][j]);
  45.                 } else {
  46.                     st[i].push_back(st[i-1][j + (1<<(i-1))]);
  47.                 }
  48.             }
  49.         }
  50.     }
  51.     int rmq(int l, int r) {
  52.         int i = log2(r - l + 1);
  53.         if (a[st[i][l]] < a[st[i][r - (1<<i) + 1]]) return st[i][l];
  54.         return st[i][r - (1<<i) + 1];
  55.     }
  56. };
  57.  
  58.  
  59. int n, q, sick[mxn], t;
  60. int dep[mxn], mxd[mxn], tin[mxn], tot[mxn], sub[mxn], par[mxn];
  61. int ccrt, is_centroid[mxn], cpar[mxn];
  62. vector<int> etour, dtour, adj[mxn], cdj[mxn];
  63. sparsemin st;
  64.  
  65. //begin tree
  66.  
  67. void dfs(int v, int p, int d) {
  68.     dep[v] = d, tin[v] = sz(etour);
  69.     par[v] = p;
  70.     etour.push_back(v);
  71.     dtour.push_back(dep[v]);
  72.     sub[v] = 1;
  73.     if (v > 1) {
  74.         adj[v].erase(find(all(adj[v]), p));
  75.     }
  76.     for (int u : adj[v]) {
  77.         dfs(u, v, d+1);
  78.         tot[v] = sz(etour);
  79.         etour.push_back(v);
  80.         dtour.push_back(dep[v]);
  81.         sub[v] += sub[u];
  82.     }
  83.     tot[v] = sz(etour);
  84.     etour.push_back(v);
  85.     dtour.push_back(dep[v]);
  86. }
  87.  
  88. int lca(int l, int r) {
  89.     int mnv = min(tin[l], tin[r]);
  90.     int mxv = max(tin[l], tin[r]);
  91.     return etour[st.rmq(mnv,mxv)];
  92. }
  93.  
  94. int dist(int u, int v) {
  95.     return dep[v] + dep[u] - 2 * dep[lca(u,v)];
  96. }
  97.  
  98. int get_centroid(int pos, int csz) {
  99.     if (csz <= 2) {
  100.         is_centroid[pos] = 1;
  101.         return pos;
  102.     }
  103.     int mxu = -1, val = -1;
  104.     for (int u : adj[pos]) {
  105.         if (!is_centroid[u]) {
  106.             if (sub[u] >= val) {
  107.                 mxu = u, val = sub[u];
  108.             }
  109.         }
  110.     }
  111.     if (!is_centroid[par[pos]]) {
  112.         if (csz - sub[pos] >= val) {
  113.             mxu = par[pos], val = csz - sub[pos];
  114.         }
  115.     }
  116.     if (val <= csz/2) {
  117.         is_centroid[pos] = 1;
  118.         return pos;
  119.     }
  120.     return get_centroid(mxu, csz);
  121. }
  122.  
  123. int centroid_decompose(int v, int csz) {
  124.     int cen = get_centroid(v, csz);
  125.  
  126.     if (csz == 1) return cen;
  127.    
  128.     int pv = par[cen];
  129.     while (!is_centroid[pv]) {
  130.         sub[pv] -= sub[cen];
  131.         if (pv == 1) break;
  132.         pv = par[pv];
  133.     }
  134.     for (int u : adj[cen]) {
  135.         if (is_centroid[u]) continue;
  136.         int nc = centroid_decompose(u, sub[u]);
  137.         cdj[cen].push_back(nc);
  138.         cpar[nc] = cen;
  139.     }
  140.     if (!is_centroid[par[cen]]) {
  141.         int nc = centroid_decompose(par[cen], csz - sub[cen]);
  142.         cdj[cen].push_back(nc);
  143.         cpar[nc] = cen;
  144.     }
  145.     return cen;
  146. }
  147.  
  148. //end tree
  149.  
  150. int sick1[mxn], mxdus[mxn];
  151. vector<vector<int>> adt[mxn]; //coords with distance i
  152. vector<int> mdwd[mxn]; //min depth with dist
  153.  
  154. bool ccsig(int a, int b) {
  155.     return (dep[a] > dep[b]);
  156. }
  157.  
  158. int get_high(int v) {
  159.     int bv = inf, bi = -1;
  160.     int v1 = v;
  161.     while (1) {
  162.         int d = dist(v, v1);
  163.         if (d > t) {
  164.             if (v1 == ccrt) break;
  165.             v1 = cpar[v1];
  166.             continue;
  167.         }
  168.         int dl = t - d;
  169.         if (sz(mdwd[v1]) <= dl) {
  170.             dl = sz(mdwd[v1]) - 1;
  171.         }
  172.         if (dl >= 0 && mdwd[v1][dl]) {
  173.             int cp = mdwd[v1][dl];
  174.             int cv = dep[cp];
  175.             if (cv < bv) {
  176.                 bv = cv;
  177.                 bi = cp;
  178.             }
  179.         }
  180.         if (v1 == ccrt) break;
  181.         v1 = cpar[v1];
  182.     }
  183.     if (bi == -1) {
  184.         return 0;
  185.     }
  186.     return bi;
  187. }
  188.  
  189. void fillin(int vv) {
  190.     int v1 = vv;
  191.     while (1) {
  192.         int dl = t - dist(vv, v1);
  193.         if (dl < 0) {
  194.             if (v1 == ccrt) break;
  195.             v1 = cpar[v1];
  196.             continue;
  197.         }
  198.         for (int i = 0; i <= dl; i++) {
  199.             if (sz(adt[v1]) <= i) break;
  200.             for (int j : adt[v1][i]) {
  201.                 sick1[j] = 0;
  202.     //          cout << v1 << " " << j << endl;
  203.             }
  204.         }
  205.         if (v1 == ccrt) break;
  206.         v1 = cpar[v1];
  207.         continue;
  208.     }
  209. }
  210.  
  211. void solve() {
  212.     cin >> t;
  213.     for (int i = 1; i <= n; i++) sick1[i] = sick[i];
  214.     for (int i = 1; i <= n; i++) {
  215.         int ml = sz(mdwd[i]);
  216.         fill(mdwd[i].begin(), mdwd[i].begin()+ml, 0);
  217.     }
  218.     //populate mdwd
  219.     for (int i = 1; i <= n; i++) {
  220.         if (mxd[i] <= t) continue;
  221.         int v = i;
  222.         while (1) {
  223.             int dt = dist(v, i);
  224.             int dep1 = dep[mdwd[v][dt]];
  225.             int dep2 = dep[i];
  226.             if (mdwd[v][dt] == 0 || dep2 < dep1) {
  227.                 mdwd[v][dt] = i;
  228.             }
  229.             if (v == ccrt) break;
  230.             v = cpar[v];
  231.         }
  232.     }
  233.     for (int i = 1; i <= n; i++) {
  234.         for (int j = 1; j <= t; j++) {
  235.             if (sz(mdwd[i]) <= j) break;
  236.             if (!mdwd[i][j-1]) continue;
  237.             if (!dep[mdwd[i][j]] || dep[mdwd[i][j-1]] < dep[mdwd[i][j]]) {
  238.                 mdwd[i][j] = mdwd[i][j-1];
  239.             }
  240.         }
  241.     }
  242.     vector<int> sig;
  243.     for (int i = 1; i <= n; i++) sig.push_back(i);
  244.     sort(all(sig), ccsig);
  245.     int ans = 0;
  246. //  for (int i = 0; i <= n; i++) {
  247. //      cout << i << ": ";
  248. //      for (auto j : mdwd[i]) cout << j << ' ';
  249. //      cout << "\n";
  250. //  }
  251.     for (auto i : sig) {
  252.         if (!sick1[i]) continue;
  253.         ans++;
  254.         int vv = get_high(i);
  255.         if (!vv) {
  256.             cout << "-1\n"; return;
  257.         }
  258.         fillin(vv);
  259.     }
  260.     cout << ans << "\n";
  261. }
  262.  
  263. signed main() {
  264.     ios::sync_with_stdio(false); cin.tie(nullptr);
  265.     auto start = high_resolution_clock::now();
  266.     cin >> n;
  267.     for (int i = 0; i < n; i++) {
  268.         char c; cin >> c;
  269.         sick[i+1] = c-'0';
  270.     }
  271.     for (int i = 1; i < n; i++) {
  272.         int u, v; cin >> u >> v;
  273.         adj[u].push_back(v); adj[v].push_back(u);
  274.     }
  275.     dfs(1,1,0);
  276.     st = sparsemin(dtour);
  277.     for (int i = 1; i <= n; i++) mxd[i] = inf;
  278.     queue<array<int,2> > bfs;
  279.     for (int i = 1; i <= n; i++) {
  280.         if (!sick[i]) {bfs.push({i,0});}
  281.     }
  282.     while (!bfs.empty()) {
  283.         int v = bfs.front()[0], d = bfs.front()[1];
  284.         bfs.pop();
  285.         if (mxd[v] <= d) continue;
  286.         mxd[v] = d;
  287.         for (int u : adj[v]) bfs.push({u,d+1});
  288.         bfs.push({par[v], d+1});
  289.     }
  290.     ccrt = centroid_decompose(1,n);
  291.  
  292.     for (int i = 1; i <= n; i++) {
  293.         int v = i;
  294.         while (1) {
  295.             int d = dist(i, v);
  296.             if (sz(adt[v]) <= d) adt[v].resize(d+1);
  297.             adt[v][d].push_back(i);
  298.             if (sz(mdwd[v]) <= d) mdwd[v].resize(d+1);
  299.             if (v == ccrt) break;
  300.             v = cpar[v];
  301.         }
  302.     }
  303.    
  304.     cin >> q;
  305.     while (q--) {
  306.         solve();
  307.     }
  308.    
  309. //  cout << "1\n1\n1\n1\n2\n5";
  310.     auto stop = high_resolution_clock::now();
  311.    
  312.     auto duration = duration_cast<microseconds>(stop - start);
  313.     double d = duration.count()*0.001;
  314.    
  315.     return 0;
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement