zoukankan      html  css  js  c++  java
  • topcoder srm 633 div1

    problem1 link

    如果两个循环之内可以跳完,那么我们只要让这些步数之内的数字组成两个数字$p,q,pleq q$,使得$p,q,x$组成三角形即可($p+qgeq x,p+xgeq q$)。

    否则,若$x$是所有数字之和的很多倍,则一开始是一直直着向前跳$m$次,剩下$r=x-msum_{i=0}^{n-1}t_{i}$,然后找到一个前缀和大于等于$r$即可。

    problem2 link

    对于某个节点$u$,假如最后一定选择该节点,那么对于节点$p$,若选它,那么$p$到$u$路径上的点都必须选,这样就成了一个最大权闭合图问题。可以用最小割来计算。

    problem3 link

    对于不同的素数,可以分开考虑。

    对于某一个素数p:用$min[i],max[i]$计算$n$个数字中每个数字最少最多含有多少个$p$。然后第$x$个数字含有的$p$要么取$min[x]$,要么取$max[x]$,因此可用2sat解决。

    code for problem1

    #include <algorithm>
    #include <vector>
    
    class PeriodicJumping {
     public:
      int minimalTime(int x, const std::vector<int> &jumps) {
        std::vector<int> copys = jumps;
        int n = static_cast<int>(copys.size());
        for (int i = 0; i < n; ++i) {
          copys.emplace_back(copys[i]);
        }
        n *= 2;
        if (x < 0) {
          x *= -1;
        }
        if (x == 0) {
          return 0;
        }
        long long s = 0;
        int max_jump = 0;
        for (int i = 0; i < n; ++i) {
          max_jump = std::max(max_jump, copys[i]);
          s += copys[i];
          long long min = std::max(0ll, max_jump - (s - max_jump));
          if (min <= x && x <= s) return i + 1;
        }
        int result = static_cast<int>(x / s * n);
        int remain = x % s;
        for (int i = 0; i < n && remain > 0; ++i) {
          remain -= copys[i];
          ++result;
        }
        return result;
      }
    };

    code for problem2

    #include <limits>
    #include <memory>
    #include <unordered_map>
    #include <vector>
    
    template <typename FlowType>
    class MaxFlowSolver {
      static constexpr FlowType kMaxFlow = std::numeric_limits<FlowType>::max();
      static constexpr FlowType kZeroFlow = static_cast<FlowType>(0);
      struct node {
        int v;
        int next;
        FlowType cap;
      };
    
     public:
      int VertexNumber() const { return used_index_; }
    
      FlowType MaxFlow(int source, int sink) {
        source = GetIndex(source);
        sink = GetIndex(sink);
    
        int n = VertexNumber();
        std::vector<int> pre(n);
        std::vector<int> cur(n);
        std::vector<int> num(n);
        std::vector<int> h(n);
        for (int i = 0; i < n; ++i) {
          cur[i] = head_[i];
          num[i] = 0;
          h[i] = 0;
        }
        int u = source;
        FlowType result = 0;
        while (h[u] < n) {
          if (u == sink) {
            FlowType min_cap = kMaxFlow;
            int v = -1;
            for (int i = source; i != sink; i = edges_[cur[i]].v) {
              int k = cur[i];
              if (edges_[k].cap < min_cap) {
                min_cap = edges_[k].cap;
                v = i;
              }
            }
            result += min_cap;
            u = v;
            for (int i = source; i != sink; i = edges_[cur[i]].v) {
              int k = cur[i];
              edges_[k].cap -= min_cap;
              edges_[k ^ 1].cap += min_cap;
            }
          }
          int index = -1;
          for (int i = cur[u]; i != -1; i = edges_[i].next) {
            if (edges_[i].cap > 0 && h[u] == h[edges_[i].v] + 1) {
              index = i;
              break;
            }
          }
          if (index != -1) {
            cur[u] = index;
            pre[edges_[index].v] = u;
            u = edges_[index].v;
          } else {
            if (--num[h[u]] == 0) {
              break;
            }
            int k = n;
            cur[u] = head_[u];
            for (int i = head_[u]; i != -1; i = edges_[i].next) {
              if (edges_[i].cap > 0 && h[edges_[i].v] < k) {
                k = h[edges_[i].v];
              }
            }
            if (k + 1 < n) {
              num[k + 1] += 1;
            }
            h[u] = k + 1;
            if (u != source) {
              u = pre[u];
            }
          }
        }
        return result;
      }
    
      MaxFlowSolver() = default;
    
      void Clear() {
        edges_.clear();
        head_.clear();
        vertex_indexer_.clear();
        used_index_ = 0;
      }
    
      void InsertEdge(int from, int to, FlowType cap) {
        from = GetIndex(from);
        to = GetIndex(to);
        AddEdge(from, to, cap);
        AddEdge(to, from, kZeroFlow);
      }
    
     private:
      int GetIndex(int idx) {
        auto iter = vertex_indexer_.find(idx);
        if (iter != vertex_indexer_.end()) {
          return iter->second;
        }
        int map_idx = used_index_++;
        head_.push_back(-1);
        return vertex_indexer_[idx] = map_idx;
      }
    
      void AddEdge(int from, int to, FlowType cap) {
        node p;
        p.v = to;
        p.cap = cap;
        p.next = head_[from];
        head_[from] = static_cast<int>(edges_.size());
        edges_.emplace_back(p);
      }
    
      std::vector<node> edges_;
      std::vector<int> head_;
    
      std::unordered_map<int, int> vertex_indexer_;
      int used_index_ = 0;
    };
    
    class DoubleTree {
     public:
      int maximalScore(const std::vector<int> &a, const std::vector<int> &b,
                       const std::vector<int> &c, const std::vector<int> &d,
                       const std::vector<int> &score) {
        int n = static_cast<int>(a.size() + 1);
        std::vector<std::vector<int>> g1(n);
        std::vector<std::vector<int>> g2(n);
        for (int i = 0; i < n - 1; ++i) {
          g1[a[i]].push_back(b[i]);
          g1[b[i]].push_back(a[i]);
          g2[c[i]].push_back(d[i]);
          g2[d[i]].push_back(c[i]);
        }
    
        constexpr int kInfiniteFlow = 1000000;
        std::unique_ptr<MaxFlowSolver<int>> solver(new MaxFlowSolver<int>());
        int result = 0;
        for (int root = 0; root < n; ++root) {
          std::vector<int> father1(n);
          std::vector<int> father2(n);
          Dfs(root, -1, father1, g1);
          Dfs(root, -1, father2, g2);
          solver->Clear();
          int source = -1;
          int sink = -2;
          int s = 0;
          for (int i = 0; i < n; ++i) {
            if (score[i] > 0) {
              s += score[i];
              solver->InsertEdge(source, i, score[i]);
            } else {
              solver->InsertEdge(i, sink, -score[i]);
            }
            if (i != root) {
              solver->InsertEdge(i, father1[i], kInfiniteFlow);
              solver->InsertEdge(i, father2[i], kInfiniteFlow);
            }
          }
          result = std::max(result, s - solver->MaxFlow(source, sink));
        }
        return result;
      }
    
     private:
      void Dfs(int u, int pre, std::vector<int> &father,
               const std::vector<std::vector<int>> &g) {
        father[u] = pre;
        for (auto e : g[u]) {
          if (e != pre) {
            Dfs(e, u, father, g);
          }
        }
      }
    };

    code for problem3

    #include <algorithm>
    #include <memory>
    #include <stack>
    #include <unordered_map>
    #include <unordered_set>
    #include <vector>
    
    class StronglyConnectedComponentSolver {
     public:
      StronglyConnectedComponentSolver() = default;
    
      void Initialize(int n) { edges_.resize(n); }
    
      std::vector<int> Solve() {
        total_ = static_cast<int>(edges_.size());
        if (total_ == 0) {
          return {};
        }
        visited_.resize(total_, false);
        low_indices_.resize(total_, 0);
        dfs_indices_.resize(total_, 0);
        connected_component_indices_.resize(total_, 0);
        for (int i = 0; i < total_; ++i) {
          if (0 == dfs_indices_[i]) {
            Dfs(i);
          }
        }
        return connected_component_indices_;
      }
    
      int VertexNumber() const { return static_cast<int>(edges_.size()); }
    
      inline void AddEdge(int from, int to) { edges_[from].push_back(to); }
    
      const std::vector<int> &Tos(int u) const { return edges_[u]; }
    
     private:
      void Dfs(const int u) {
        low_indices_[u] = dfs_indices_[u] = ++index_;
        stack_.push(u);
        visited_[u] = true;
        for (auto v : edges_[u]) {
          if (0 == dfs_indices_[v]) {
            Dfs(v);
            low_indices_[u] = std::min(low_indices_[u], low_indices_[v]);
          } else if (visited_[v]) {
            low_indices_[u] = std::min(low_indices_[u], dfs_indices_[v]);
          }
        }
        if (dfs_indices_[u] == low_indices_[u]) {
          int v = 0;
          do {
            v = stack_.top();
            stack_.pop();
            visited_[v] = false;
            connected_component_indices_[v] = connected_component_index_;
          } while (u != v);
          ++connected_component_index_;
        }
      }
    
      std::vector<std::vector<int>> edges_;
      int total_ = 0;
      std::vector<bool> visited_;
      std::vector<int> low_indices_;
      std::vector<int> dfs_indices_;
      std::stack<int> stack_;
      int index_ = 0;
      int connected_component_index_ = 0;
      std::vector<int> connected_component_indices_;
    };
    
    class TwoSatisfiabilitySolver {
     public:
      void Initialize(int total_vertex_number) {
        scc_solver_.Initialize(total_vertex_number);
      }
    
      // If idx1 is type1, then idx2 must be type2.
      void AddConstraint(int idx1, bool type1, int idx2, bool type2) {
        int from = idx1 * 2 + (type1 ? 1 : 0);
        int to = idx2 * 2 + (type2 ? 1 : 0);
        scc_solver_.AddEdge(from, to);
      }
    
      void AddConflict(int idx1, bool type1, int idx2, bool type2) {
        AddConstraint(idx1, type1, idx2, !type2);
        AddConstraint(idx2, type2, idx1, !type1);
      }
    
      void AddLead(int idx1, bool type1, int idx2, bool type2) {
        AddConstraint(idx1, type1, idx2, type2);
        AddConstraint(idx2, !type2, idx1, !type1);
      }
    
      // The idx must not be type
      void SetFalse(int idx, bool type) { SetTrue(idx, !type); }
    
      // The idx must be type
      void SetTrue(int idx, bool type) { AddConstraint(idx, !type, idx, type); }
    
      bool ExistSolution() {
        if (scc_indices_.empty()) {
          scc_indices_ = scc_solver_.Solve();
          total_scc_number_ =
              *std::max_element(scc_indices_.begin(), scc_indices_.end()) + 1;
        }
        for (int i = 0; i < scc_solver_.VertexNumber() / 2; ++i) {
          if (scc_indices_[i * 2] == scc_indices_[i * 2 + 1]) {
            return false;
          }
        }
        return true;
      }
    
      std::vector<bool> GetOneSolution() {
        if (!ExistSolution()) {
          return {};
        }
        BuildNewGraph();
        TopSort();
        int total = scc_solver_.VertexNumber();
        std::vector<bool> result(total / 2);
        for (int e = 0; e < total / 2; ++e) {
          if (last_color_[scc_indices_[e * 2]] == 0) {
            result[e] = false;
          } else {
            result[e] = true;
          }
        }
        return std::move(result);
      }
    
     private:
      void BuildNewGraph() {
        new_edges_.resize(total_scc_number_);
        new_graph_node_in_degree_.resize(total_scc_number_, 0);
        int total = scc_solver_.VertexNumber();
        for (int i = 0; i < total; ++i) {
          int scc0 = scc_indices_[i];
          for (auto e : scc_solver_.Tos(i)) {
            int scc1 = scc_indices_[e];
            if (scc0 != scc1 &&
                new_edges_[scc1].find(scc0) == new_edges_[scc1].end()) {
              new_edges_[scc1].insert(scc0);
              ++new_graph_node_in_degree_[scc0];
            }
          }
        }
      }
    
      void TopSort() {
        std::vector<int> conflict(total_scc_number_);
        int total = scc_solver_.VertexNumber() / 2;
        for (int i = 0; i < total; ++i) {
          conflict[scc_indices_[i * 2]] = scc_indices_[i * 2 + 1];
          conflict[scc_indices_[i * 2 + 1]] = scc_indices_[i * 2];
        }
        last_color_.resize(total_scc_number_, -1);
        std::stack<int> st;
        for (int i = 0; i < total_scc_number_; ++i) {
          if (0 == new_graph_node_in_degree_[i]) {
            st.push(i);
          }
        }
        while (!st.empty()) {
          int u = st.top();
          st.pop();
          if (last_color_[u] == -1) {
            last_color_[u] = 0;
            last_color_[conflict[u]] = 1;
          }
          for (auto e : new_edges_[u]) {
            int cur = --new_graph_node_in_degree_[e];
            if (cur == 0) {
              st.push(e);
            }
          }
        }
      }
    
      std::vector<int> scc_indices_;
      int total_scc_number_ = 0;
      std::vector<std::unordered_set<int>> new_edges_;
      std::vector<int> new_graph_node_in_degree_;
      std::vector<int> last_color_;
    
      StronglyConnectedComponentSolver scc_solver_;
    };
    
    class GCDLCM {
     public:
      std::string possible(int n, const std::string &type,
                           const std::vector<int> &A, const std::vector<int> &B,
                           const std::vector<int> &C) {
        std::unordered_set<int> primes;
        for (auto c : C) {
          for (int i = 2; i * i <= c; ++i) {
            if (c % i == 0) {
              primes.insert(i);
              while (c % i == 0) {
                c /= i;
              }
            }
          }
          if (c > 1) {
            primes.insert(c);
          }
        }
        int m = static_cast<int>(C.size());
        auto Check = [&](int p) {
          std::vector<int> min(n, 0);
          std::vector<int> max(n, 1000);
          std::vector<int> number(m, 0);
    
          for (int i = 0; i < m; ++i) {
            int t = C[i];
            while (t % p == 0) {
              ++number[i];
              t /= p;
            }
            if (type[i] == 'G') {
              min[A[i]] = std::max(min[A[i]], number[i]);
              min[B[i]] = std::max(min[B[i]], number[i]);
            } else {
              max[A[i]] = std::min(max[A[i]], number[i]);
              max[B[i]] = std::min(max[B[i]], number[i]);
            }
          }
          for (int i = 0; i < n; ++i) {
            if (min[i] > max[i]) {
              return false;
            }
          }
          std::unique_ptr<TwoSatisfiabilitySolver> solver(
              new TwoSatisfiabilitySolver());
          solver->Initialize(n * 2);
          for (int i = 0; i < m; i++) {
            int u = A[i];
            int v = B[i];
            if (type[i] == 'G') {
              bool x = min[u] > number[i];
              bool y = min[v] > number[i];
              if (x && y) {
                return false;
              } else if (x) {
                if (min[v] != max[v]) {
                  solver->SetTrue(v, false);
                }
              } else if (y) {
                if (min[u] != max[u]) {
                  solver->SetTrue(u, false);
                }
              } else {
                if (min[v] != max[v] && min[u] != max[u]) {
                  solver->AddConstraint(v, true, u, false);
                  solver->AddConstraint(u, true, v, false);
                }
              }
            } else {
              bool x = max[u] < number[i];
              bool y = max[v] < number[i];
              if (x && y) {
                return false;
              } else if (x) {
                if (min[v] != max[v]) {
                  solver->SetTrue(v, true);
                }
              } else if (y) {
                if (min[u] != max[u]) {
                  solver->SetTrue(u, true);
                }
              } else {
                if (min[v] != max[v] && min[u] != max[u]) {
                  solver->AddConstraint(v, false, u, true);
                  solver->AddConstraint(u, false, v, true);
                }
              }
            }
          }
          return solver->ExistSolution();
        };
        for (auto p : primes) {
          if (!Check(p)) {
            return "Solution does not exist";
          }
        }
        return "Solution exists";
      }
    };
  • 相关阅读:
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线接收
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线发送
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线发送
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线发送
    图形化编程娱乐于教,Kittenblock arduino实例,液晶屏显示
    图形化编程娱乐于教,Kittenblock arduino实例,数码管计时器
    图形化编程娱乐于教,Kittenblock arduino实例,超声波测距
    超级简单的Android Studio jni 实现(无需命令行)
    实现ViewPager懒加载的三种方法
    MySQL安装
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/3979562.html
Copyright © 2011-2022 走看看