zoukankan      html  css  js  c++  java
  • BZOJ #2506. calc [根号分治,莫队,二分]

    (p) 是个正常范围, (sqrt p <= 100) 比较小,预处理出来 (a_i % p == k) 的位置,然后丢进去,最后询问的 (p) 如果大于 (100) 就莫队搞,否则直接二分。

    // powered by c++11
    // by Isaunoya
    #include <bits/stdc++.h>
    #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
    #define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
    using namespace std;
    using db = double;
    using ll = long long;
    using uint = unsigned int;
    #define int long long
    using pii = pair<int, int>;
    #define ve vector
    #define Tp template
    #define all(v) v.begin(), v.end()
    #define sz(v) ((int)v.size())
    #define pb emplace_back
    #define fir first
    #define sec second
    // the cmin && cmax
    Tp<class T> void cmax(T& x, const T& y) {
      if (x < y) x = y;
    }
    Tp<class T> void cmin(T& x, const T& y) {
      if (x > y) x = y;
    }
    // sort , unique , reverse
    Tp<class T> void sort(ve<T>& v) { sort(all(v)); }
    Tp<class T> void unique(ve<T>& v) {
      sort(all(v));
      v.erase(unique(all(v)), v.end());
    }
    Tp<class T> void reverse(ve<T>& v) { reverse(all(v)); }
    const int SZ = 0x191981;
    struct FILEIN {
      ~FILEIN() {}
      char qwq[SZ], *S = qwq, *T = qwq, ch;
      char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq, 1, SZ, stdin), S == T) ? EOF : *S++; }
      FILEIN& operator>>(char& c) {
        while (isspace(c = GETC()))
          ;
        return *this;
      }
      FILEIN& operator>>(string& s) {
        while (isspace(ch = GETC()))
          ;
        s = ch;
        while (!isspace(ch = GETC())) s += ch;
        return *this;
      }
      Tp<class T> void read(T& x) {
        bool sign = 1;
        while ((ch = GETC()) < 0x30)
          if (ch == 0x2d) sign = 0;
        x = (ch ^ 0x30);
        while ((ch = GETC()) > 0x2f) x = x * 0xa + (ch ^ 0x30);
        x = sign ? x : -x;
      }
      FILEIN& operator>>(int& x) { return read(x), *this; }
      FILEIN& operator>>(signed& x) { return read(x), *this; }
      FILEIN& operator>>(unsigned& x) { return read(x), *this; }
    } in;
    struct FILEOUT {
      const static int LIMIT = 0x114514;
      char quq[SZ], ST[0x114];
      signed sz, O;
      ~FILEOUT() { sz = O = 0; }
      void flush() {
        fwrite(quq, 1, O, stdout);
        fflush(stdout);
        O = 0;
      }
      FILEOUT& operator<<(char c) { return quq[O++] = c, *this; }
      FILEOUT& operator<<(string str) {
        if (O > LIMIT) flush();
        for (char c : str) quq[O++] = c;
        return *this;
      }
      Tp<class T> void write(T x) {
        if (O > LIMIT) flush();
        if (x < 0) {
          quq[O++] = 0x2d;
          x = -x;
        }
        do {
          ST[++sz] = x % 0xa ^ 0x30;
          x /= 0xa;
        } while (x);
        while (sz) quq[O++] = ST[sz--];
        return;
      }
      FILEOUT& operator<<(int x) { return write(x), *this; }
      FILEOUT& operator<<(signed x) { return write(x), *this; }
      FILEOUT& operator<<(unsigned x) { return write(x), *this; }
    } out;
    
    int n, q;
    vector<int> qwq[101][101];
    const int S = 400;
    const int maxn = 1e5 + 51;
    int a[maxn];
    int bl(int x) { return (x - 1) / S + 1; }
    int ans[maxn];
    signed main() {
    #ifdef _WIN64
      freopen("testdata.in", "r", stdin);
    #endif
      // code begin.
      in >> n >> q;
      rep(i, 1, n) in >> a[i];
      rep(i, 1, n) rep(j, 1, 100) qwq[j][a[i] % j].push_back(i);
      struct node {
        int l, r, p, k, id;
        bool operator<(const node& o) const {
          if (bl(l) ^ bl(o.l)) return l < o.l;
          return r < o.r;
        }
      };
      vector<node> que;
      rep(i, 1, q) {
        int l, r, p, k;
        in >> l >> r >> p >> k;
        if (p <= 100)
          ans[i] = upper_bound(all(qwq[p][k]), r) - lower_bound(all(qwq[p][k]), l);
        else
          que.push_back({ l, r, p, k, i });
      }
      sort(que);
      int l = 1, r = 0;
      vector<int> cnt(maxn);
      for (auto x : que) {
        while (l < x.l) --cnt[a[l++]];
        while (l > x.l) ++cnt[a[--l]];
        while (r < x.r) ++cnt[a[++r]];
        while (r > x.r) --cnt[a[r--]];
        int res = 0;
        for (int ovo = x.k; ovo <= 10000; ovo += x.p) res += cnt[ovo];
        ans[x.id] = res;
      }
      rep(i, 1, q) out << ans[i] << '
    ';
      return out.flush(), 0;
      // code end.
    }
    
  • 相关阅读:
    apply call bind方法的区别和含义
    html头部meta标签
    语义化标签
    “文件名和url路径名”命名要点以及大小写问题
    BMP GIF PNG JPG等图片格式的区别和适用情况
    前端页面的性能优化
    js阻止默认事件,如a标签跳转和事件冒泡
    散列碰撞问题的解决——开链法(拉链法)
    substring()方法
    对学生成绩进行散列
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12294462.html
Copyright © 2011-2022 走看看