• LOJ2319. 「NOIP2017」列队【线段树】


    LINK

    思路

    神仙线段树

    你考虑怎么样才能快速维护出答案

    首先看看一条链怎么做?

    首先很显然的思路是维护每个节点的是否出过队

    然后对于重新入队的点

    直接在后面暴力vector存一下就可以了

    最核心的思路就是假设你已经知道了当前位置的点是什么编号,最后通过计算/查询来得出答案

    然后不是链的情况其实就动态开点就可以了

    因为有用的状态很少

    然后就直接进行查询就可以了


    //Author: dream_maker
    #include<bits/stdc++.h>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) {
        x = (x<<1) + (x<<3) + c -'0';
        c = getchar();
      }
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) {
        putchar('-');
        x = -x;
      }
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    const int N = 3e5 + 10;
    const int LOG = 40;
    int tot = 0, n, m, q, p;
    int rt[N], ls[N * LOG], rs[N * LOG], siz[N * LOG];
    vector<ll> v[N];
    void insert(int &t, int l, int r, int pos) {
      if (!t) t = ++tot;
      ++siz[t];
      if (l == r) return;
      int mid = (l + r) >> 1;
      if (pos <= mid) insert(ls[t], l, mid, pos);
      else insert(rs[t], mid + 1, r, pos);
    }
    int query(int t, int l, int r, int k) {
      if (l == r) return l;
      int mid = (l + r) >> 1, sizl = mid - l + 1 - siz[ls[t]];
      if (k <= sizl) return query(ls[t], l, mid, k);
      else return query(rs[t], mid + 1, r, k - sizl);
    }
    ll query_single_row(ll x, ll y) {
      ll res = query(rt[0], 1, p, x);
      insert(rt[0], 1, p, res);
      ll id = (res <= n) ? res * m : v[0][res - n - 1];
      v[0].push_back(y ? y : id);
      return id;
    }
    ll query_single_line(ll x, ll y) {
      ll res = query(rt[x], 1, p, y);
      insert(rt[x], 1, p, res);
      ll id = (res < m) ? (x - 1) * m + res : v[x][res - m];
      v[x].push_back(query_single_row(x, id));
      return id;
    }
    int main() {
    #ifdef dream_maker
      freopen("input.txt", "r", stdin);
    #endif
      Read(n), Read(m), Read(q);
      p = max(n, m) + q;
      fu(i, 1, q) {
        int x, y; Read(x), Read(y);
        if (y == m) Write(query_single_row(x, 0));
        else Write(query_single_line(x, y));
        putchar('
    ');
      }
      return 0;
    }
    
  • 相关阅读:
    封装tip控件
    Javascirpt中创建对象的几种方式
    使用Servlet上传文件
    Struts2 基本配置
    使用JQuery实现手风琴布局
    winform下自绘提示框风格窗体
    环形进度条
    Oracle中获取当前时间半小时前的时间
    JSTL+MyEclipse8.5+Tomcat配置
    使用CSS和jQuery实现对话框
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9898035.html
Copyright © 2020-2023  润新知