由不勤劳的图书管理员带入了分块的坑,深深地被其暴力与优雅所征服。分块的实质就是将暴力块状封装起来,一整块的部分就一整块处理,零碎的部分就怎么暴力怎么来。因为分块大小的原因,限制了零碎部分数据的数量级,所以复杂度得以保证。

1.教主的魔法:可以算得上是一个分块的板子题。对于每一个块内sort排序,保存id值。对于修改,块内的找到点暴力修改之后重新排序,一整个块的不改变相对大小关系,所以直接外部记录累加的值。查询也一样,块外暴力,块内二分查找。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 2000000
#define maxb 1050
int n, q, B, sum[maxb], a[maxn], cnt[maxb];
struct node
{
int v, id;
}c[maxb][maxb]; int read()
{
int x = ;
char c;
c = getchar();
while(c < '' || c > '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} bool cmp(node a, node b)
{
return a. v < b.v;
} void Vio_C(int b, int x, int w)
{
c[b][x].v += w;
} void Change(int L, int R, int W)
{
int a = L / B, b = R / B;
if(a == b)
{
for(int i = ; i <= cnt[a]; i ++)
if(c[a][i].id >= L && c[a][i].id <= R) Vio_C(a, i, W);
sort(c[a] + , c[a] + cnt[a] + , cmp);
     return 0;
}
for(int i = ; i <= cnt[a]; i ++)
if(c[a][i].id >= L) Vio_C(a, i, W);
sort(c[a] + , c[a] + cnt[a] + , cmp);
for(int i = ; i <= cnt[b]; i ++)
if(c[b][i].id <= R) Vio_C(b, i, W);
sort(c[b] + , c[b] + cnt[b] + , cmp);
for(int i = a + ; i < b; i ++)
sum[i] += W;
} int check(int b, int C)
{
C -= sum[b];
int ans = cnt[b] + , l = , r = cnt[b];
while(l <= r)
{
int mid = (l + r) >> ;
if(c[b][mid].v >= C) ans = mid, r = mid - ;
else l = mid + ;
}
return cnt[b] - ans + ;
} void Query(int L, int R, int C)
{
int a = L / B, b = R / B;
int ans = ;
if(a == b)
{
C -= sum[a];
for(int i = ; i <= cnt[a]; i ++)
if(c[a][i].id >= L && c[a][i].id <= R && c[a][i].v >= C) ans ++;
printf("%lld\n", ans);
return;
}
for(int i = ; i <= cnt[a]; i ++)
if(c[a][i].id >= L && c[a][i].v + sum[a] >= C) ans ++;
for(int i = ; i <= cnt[b]; i ++)
if(c[b][i].id <= R && c[b][i].v + sum[b] >= C) ans ++;
for(int i = a + ; i < b; i ++)
ans += check(i, C);
printf("%lld\n", ans);
return;
} signed main()
{
n = read(), q = read();
B = sqrt(n);
for(int i = ; i <= n; i ++)
{
a[i] = read(); int block = i / B;
c[block][++ cnt[block]].v = a[i];
c[block][cnt[block]].id = i;
if(((i / B) != (i + ) / B) || i == n)
sort(c[block] + , c[block] + cnt[block] + , cmp);
}
for(int i = ; i <= q; i ++)
{
char c; cin >> c;
int L = read(), R = read(), W = read();
if(c == 'M') Change(L, R, W);
else Query(L, R, W);
}
return ;
}

2.不勤劳的图书管理员

这题首先注意到交换a,b的位置,只会影响到a,b之间的数。在一段区间里,a对杂乱值的贡献是多少?不难发现=在a之前且应当在a之后的书本杂乱值之和+v[a]*前面书本的个数。所以我们对每一个块使用两个树状数组,一个纪录个数,一个记录页数的前缀和,块内的利用树状数组快速查询,块外的暴力枚举计算即可。

因为此题代码是Kuai的(那个时候还不会写分块),所以就不贴代码啦。

【算法】分块——教主的魔法&不勤劳的图书管理员的更多相关文章

  1. 【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT

    [bzoj4889]: [Tjoi2017]不勤劳的图书管理员 题目大意:给定一个序列(n<=50000),每个数有一个编码ai(ai<=50000)和权值vi(vi<=100000 ...

  2. 【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组

    [BZOJ4889][Tjoi2017]不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让 ...

  3. 【loj2639】[Tjoi2017]不勤劳的图书管理员

    #2639. 「TJOI2017」不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产 ...

  4. 【BZOJ4889】不勤劳的图书管理员(树套树)

    [BZOJ4889]不勤劳的图书管理员(树套树) 题面 又是权限题,烦死了 洛谷真好 题解 分开考虑每一次交换产生的贡献. 假设交换\((x,y)\) 检查\(x\)与\(y\)对于区间\([x+1, ...

  5. 洛谷P3759 - [TJOI2017]不勤劳的图书管理员

    Portal Description 给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\l ...

  6. [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)

    题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度.现在有n本被打乱顺序的书 ...

  7. 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分

    题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...

  8. [TJOI2017]不勤劳的图书管理员(分块+树状数组)

    有一个数组开大会MLE开小会RE的做法:就是树套树,即树状数组套主席树,这种方法比较暴力,然而很遗憾它不能通过,因为其时空复杂度均为O(nlog2n). 想到一种不怎么耗内存,以时间换空间,分块!单次 ...

  9. luogu3759 [TJOI2017]不勤劳的图书管理员

    分块+权值逆序对 #include <algorithm> #include <iostream> #include <cstdio> #include <c ...

随机推荐

  1. python之打印九九乘法表

    配置环境:python 3.6 python编辑器:pycharm 整理成代码如下: #!/usr/bin/env python #-*- coding: utf-8 -*- #九九乘法表 #分析:九 ...

  2. Python学习第二弹

    昨天补充: 编码: Unicode ; utf-8 ; GBK       关系:   关键字:1. continue 终止当前循环,进行下一次循环 2. break      终止循环 题6解法2: ...

  3. Leecode刷题之旅-C语言/python-101对称二叉树

    /* * @lc app=leetcode.cn id=101 lang=c * * [101] 对称二叉树 * * https://leetcode-cn.com/problems/symmetri ...

  4. (译)JavaScript 中的正则表达式(RegEx)实操——快速掌握正则表达式,伴有随手可练的例子————(翻译未完待续)

    (原文:https://blog.bitsrc.io/a-beginners-guide-to-regular-expressions-regex-in-javascript-9c58feb27eb4 ...

  5. Win10正式版激活

    参考:https://jingyan.baidu.com/article/47a29f2457af76c015239942.html https://jingyan.baidu.com/article ...

  6. 查看sql 作业明细及运行记录

    --查看作业明细及状态 select j.name 'Job名', j.description '描述', j.ENABLED job_enabled, cast(js.last_run_date a ...

  7. PHP.41-TP框架商城应用实例-后台16-商品属性2-AJAX添加、删除

     添加商品属性 思路:根据[后台15]类型表{id,type_name}与属性表{id,attr_name,attr_type,attr_option_values,type_id} 1.建表商品属性 ...

  8. struts2官方 中文教程 系列十二:控制标签

    介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...

  9. 深度学习:激活函数的比较和优缺点,sigmoid,tanh,relu

    https://blog.csdn.net/u011684265/article/details/78039280

  10. php之apc浅探

    扩展编译: ./configure --enable-apc --with-php-config=/usr/local/php/bin/php-config --prefix=/usr/local/a ...