loj数列分块入门(下)

简介: 入门 6-单点插入-单点查询入门 7-区间乘法-区间加法-单点查询入门 8-区间修改-区间查询入门 9-区间查询众数

入门 6-单点插入-单点查询


d58727ec204d4ab3964f316c895a0857.png

typedef pair<int,int> PII;
ll n,a[maxn];
ll blk,lazy[maxn],b[maxn],sum[maxn],tot;
vector<int> vet[maxn];
void reBuild() {
  int p = 0;
  for(int i=1; i<=tot; i++) {
    for(int val : vet[i]) {
      a[++p] = val;
    }
    vet[i].clear();
  }
  blk = sqrt(p);
  tot = ceil(1.0 * p / blk);
  for(int i=1; i<=p; i++) {
    b[i] = (i - 1) / blk + 1;
    vet[b[i]].push_back(a[i]);
  }
}
PII query(ll r) {
  for(int i=1; i<=tot; i++) {
    if(r > vet[i].size()) r -= vet[i].size();
    else return {i,r-1};
  }
}
void insert(ll l,ll r) {
  PII t = query(l);
  vet[t.first].insert(vet[t.first].begin() + t.second,r);
  if(vet[t.first].size() > 10 * blk) reBuild();
}
int main() {
  n = read;
  for(int i=1; i<=n; i++) a[i] = read;
  blk = sqrt(n);
  tot = ceil(1.0*n / blk);
  for(int i=1; i<=n; i++) {
    b[i] = (i - 1) / blk + 1;
    vet[b[i]].push_back(a[i]);
  }
  for(int i=1; i<=n; i++) {
    int op = read,l = read,r = read,c = read;
    if(op == 0) insert(l,r);
    else {
      PII t = query(r);
      printf("%d\n",vet[t.first][t.second]);
    }
  }
  return 0;
}
/**
4
1 2 2 3
0 1 3 1
1 1 4 4
0 1 2 2
1 1 2 4
2
3
**/


入门 7-区间乘法-区间加法-单点查询


ad6d9dc750354814ac34840b17a5e3dd.png


const int maxn = 1e5 + 7;
const int mod = 10007;
ll n,a[maxn];
ll blk,add[maxn],b[maxn],sum[maxn],mul[maxn];
void pushDown(int id) {
  for(int i=(id-1) * blk + 1; i<=min(id * blk,n); i++) {
    a[i] = (a[i] * mul[id] % mod + add[id] + mod) % mod;
  }
  mul[id] = 1;
  add[id] = 0;
}
void add_mul(int l,int r,ll val,int op) {
  pushDown(b[l]);
  for(int i=l; i<=min(b[l]*blk,1LL*r); i++) {
    if(op) a[i] = (a[i] * val) % mod;
    else a[i] = (a[i] + val) % mod;
  }
  if(b[l] != b[r]) {
    pushDown(b[r]);
    for(int i=(b[r]-1)*blk + 1; i<=r; i++) {
      if(op) a[i] = (a[i] * val) % mod;
      else a[i] = (a[i] + val) % mod;
    }
  }
  for(int i=b[l]+1; i<=b[r]-1; i++) {
    if(op) mul[i] = (mul[i] * val) % mod,add[i] = (add[i] * val) % mod;
    else add[i] = (add[i] + val) % mod;
  }
}
ll query(int r) {
  ll ret = 0;
  ret = (a[r] * mul[b[r]] % mod + add[b[r]]) % mod;
  return ret;
}
int main() {
  n = read;
  for(int i=1; i<=n; i++) a[i] = read;
  blk = sqrt(n);
  for(int i=1; i<=n; i++) {
    b[i] = (i - 1) / blk + 1;
    mul[b[i]] = 1;
    add[b[i]] = 0;
  }
  for(int i=1; i<=n; i++) {
    int op = read,l = read,r = read,c = read;
    if(op == 2) {
      printf("%lld\n",query(r));
    } else {
      add_mul(l,r,c,op);
    }
  }
  return 0;
}
/**
7
1 2 2 3 9 3 2
0 1 3 1
2 1 3 1
1 1 4 4
0 1 7 2
1 2 6 4
1 1 6 5
2 2 6 4
3
100
**/


入门 8-区间修改-区间查询


f5096dfded274f9ab2da7d2f729d5f72.png


ll n,a[maxn];
ll blk,add[maxn],b[maxn],upd[maxn];
void reset(int id) {
  if(upd[id] == -1) return ;
  for(int i=(id-1) * blk+1; i<=min(id*blk,n); i++) {
    a[i] = upd[id];
  }
  upd[id] = -1;
}
ll getSet(int l,int r,ll val) {
  ll ans = 0;
  reset(b[l]);
  for(int i=l; i<=min(b[l]*blk,1LL*r); i++) {
    ans += a[i] == val;
    a[i] = val;
  }
  if(b[l] != b[r]) {
    reset(b[r]);
    for(int i=(b[r]-1)*blk + 1; i<=r; i++) {
      ans += a[i] == val;
      a[i] = val;
    }
  }
  for(int i=b[l]+1; i<=b[r]-1; i++) {
    if(upd[i] == -1) {
      for(int j=(i-1)*blk+1; j<=i*blk; j++) {
        ans += a[j] == val;
      }
    } else ans += upd[i] == val?blk:0;
    upd[i] = val;
  }
  return ans;
}
int main() {
  n = read;
  for(int i=1; i<=n; i++) a[i] = read;
  blk = sqrt(n);
  for(int i=1; i<=n; i++) {
    b[i] = (i - 1) / blk + 1;
    upd[b[i]] = -1;
  }
  for(int i=1; i<=n; i++) {
    int l = read,r = read,c = read;
    ll ans = getSet(l,r,c);
    printf("%lld\n",ans);
  }
  return 0;
}
/**
4
1 2 2 4
1 3 1
1 4 4
1 2 2
1 4 2
1
1
0
2
**/


入门 9-区间查询众数


50cdd803b21b4d79bd89c58a9b5792f3.png


#define Clear(x,val) memset(x,val,sizeof x)
ll n,a[maxn],ans[2007][2007],b[maxn],blk,cnt[maxn],num;
vector<int> vet[maxn];
map<int,int> vis,val;
void get(int id) {
  Clear(cnt,0);
  int mx = 0,res = 0;
  for(int i=(id-1) * blk + 1; i<=n; i++) {
    int to = b[i];///cur is the b[i]-th blk
    ++ cnt[a[i]];/// the amt ++
    if(cnt[a[i]] > mx || (cnt[a[i]] == mx && val[a[i]] < val[res])) {
      res = a[i];/// set the cur mx value
      mx = cnt[a[i]];
    }
    ans[id][to] = res;/// from blk id -> blk to  the ans = res
  }
}
int getNum(int l,int r,int x) {
  int ret = 0;
  ret = upper_bound(vet[x].begin(),vet[x].end(),r) - lower_bound(vet[x].begin(),vet[x].end(),l);/// amount of x
  return ret;
}
ll query(int l,int r) {
  ll ret = ans[b[l] + 1][b[r] - 1];// center blks
  int mx = getNum(l,r,ret);// get the amount of this
  for(int i=l; i<=min(r*1LL,b[l]*blk); i++) {
    int amt = getNum(l,r,a[i]);
    if(amt > mx || (amt == mx && val[a[i]] < val[ret])) { ///val[ret]
      ret = a[i];
      mx = amt;
    }
  }
  if(b[l] != b[r]) {
    for(int i = (b[r] - 1) * blk + 1; i<=r; i++) {
      int amt = getNum(l,r,a[i]);
      if(amt > mx || (amt == mx && val[a[i]] < val[ret])) {
        ret = a[i];
        mx = amt;
      }
    }
  }
  return val[ret];
}
int main() {
  n = read;
  blk = sqrt(n);
  blk = 80;
  for(int i=1; i<=n; i++) {
    a[i] = read;
    b[i] = (i - 1) / blk + 1;
    if(!vis[a[i]]) {
      vis[a[i]] = ++ num;
      val[num] = a[i];///¶ÔÓ¦ÏÂ
    }
    a[i] = vis[a[i]];
    vet[a[i]].push_back(i);
  }
  for(int i=1; i<=b[n]; i++) get(i); /// get the i-th blk
  for(int i=1; i<=n; i++) {
    int l = read,r = read;
    if(l > r) swap(l,r);
    ll ans = query(l,r);
    printf("%lld\n",ans);
  }
  return 0;
}
/**
4
1 2 2 4
1 2
1 4
2 4
3 4
1
2
2
2
**/


目录
相关文章
|
算法 容器
算法:双指针解决数组划分和数组分块问题
算法:双指针解决数组划分和数组分块问题
|
算法 C++
剑指offer(C++)-JZ41:数据流中的中位数(算法-排序)
剑指offer(C++)-JZ41:数据流中的中位数(算法-排序)
剑指offer(C++)-JZ41:数据流中的中位数(算法-排序)
|
6月前
|
存储 算法 前端开发
前端算法-合并两个有序数组
前端算法-合并两个有序数组
|
6月前
|
存储 机器学习/深度学习 人工智能
【408数据结构与算法】—数组和特殊矩阵的压缩存储(二十五)
【408数据结构与算法】—数组和特殊矩阵的压缩存储(二十五)
|
人工智能 算法 JavaScript
[数据结构与算法]基础算法(排序, 二分, 前缀, 差分)
快速排序:(分治的思想)✅ 确定分界点:q[l], q[(r+l)/2], q[r] (中间点可以随机选, 按照同一规则, 这里选(l+r)/2该点) 维护数组:维护分界点的左边都比分界点小,分界点的右边都比分界点大 按照维护关系, 递归处理左右两段 💡思想解释: 先整后细:先让大体总的符合条件,再部分部分解决
|
人工智能 vr&ar
数列分块入门 1 (单点查值,区间加法)
数列分块入门 1 (单点查值,区间加法)
80 0
|
存储
剑指offer 42. 数据流中的中位数
剑指offer 42. 数据流中的中位数
42 0
|
人工智能 索引
Leecode 1013. 将数组分成和相等的三个部分
Leecode 1013. 将数组分成和相等的三个部分
74 0
|
存储 5G 容器
一个很大的文件,存放了10G个整数的乱序数列,如何用程序找出中位数。
一个很大的文件,存放了10G个整数的乱序数列,如何用程序找出中位数。
100 0
|
人工智能
LOJ—— 数列分块入门 2
LOJ—— 数列分块入门 2
86 0