思路:

莫队算法+树状数组。

莫队算法的基本思想是对大量要查询的区间进行离线处理,按照一定的顺序计算,来降低复杂度。概括来说,我们在知道了[l, r]的解,并且可以通过一个较低的复杂度推出[l - 1, r], [l, r - 1], [l + 1, r], [l, r + 1]的解的情况下,则可使用该算法。

对该算法比较好的介绍:

1.https://blog.sengxian.com/algorithms/mo-s-algorithm

2.http://blog.csdn.net/bossup/article/details/39236275

在本题中,对于一个区间[l, r],实际上是求a[l] * (r - l + 1) + a[l + 1] * (r - l) +... + a[r] * 1。

那么在知道了[l, r]的解的前提下,如何转移到[l', r']呢?

我们可以观察一个简单的情况:[l, r] -> [l - 1, r]。比如[1, 2, 3, 4] -> [3, 1, 2, 3, 4]。

对于这个例子,假设原来的解为res。那么在左边加上一个‘3’之后,新的解res_new为

1 * 5 + 2 * 4 + 3 * 3 + 3 * 2 + 4 * 1 =

1 * 4 + 2 * 3 + 3 * 2 + 4 * 1 + 1 + 2 + 3 * 3 =

res + 1 + 2 + 3 * 3。

实际上就是原来的解res + 原来的区间内比3小的数的和 + 3 * (原来的区间内大于等于3的数的个数 + 1);

反过来,[3, 1, 2, 3, 4] -> [1, 2, 3, 4]的过程类似。

我们可以使用两个树状数组来维护变化的部分。具体来说其中一个维护大于等于3的数的个数,另一个维护小于3的数的和即可。

实现:

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll; const int N = ; int t, n, m, L, R, a[N + ], block;
ll tot = , ans[N + ];
ll bit1[N + ]; //统计个数
ll bit2[N + ]; //统计和 struct query
{
int l, r, id;
};
query Q[N + ]; bool cmp(const query & x, const query & y)
{
if (x.l / block != y.l / block)
return x.l / block < y.l / block;
return x.r < y.r;
} void bit_add(ll * bit, int i, int x)
{
if (i == )
return;
while (i <= N)
{
bit[i] += x;
i += i & -i;
}
} ll bit_sum(ll * bit, int i)
{
ll s = ;
while (i)
{
s += bit[i];
i -= i & -i;
}
return s;
} ll bit_query(ll * bit, int l ,int r)
{
return bit_sum(bit, r) - bit_sum(bit, l - );
} void Add(int pos)
{
tot += (ll)a[pos] * (bit_query(bit1, a[pos], N + ) + );
tot += bit_query(bit2, , a[pos] - );
bit_add(bit1, a[pos], );
bit_add(bit2, a[pos], a[pos]);
} void Del(int pos)
{
tot -= (ll)a[pos] * bit_query(bit1, a[pos], N + );
tot -= bit_query(bit2, , a[pos] - );
bit_add(bit1, a[pos], -);
bit_add(bit2, a[pos], -a[pos]);
} void init()
{
block = sqrt(n);
L = R = ;
tot = a[];
memset(bit1, , sizeof(bit1));
memset(bit2, , sizeof(bit2));
bit_add(bit1, a[], );
bit_add(bit2, a[], a[]);
} int main()
{
cin >> t;
while (t--)
{
cin >> n >> m;
for (int i = ; i <= n; i++)
{
scanf("%d", &a[i]);
}
init();
for (int i = ; i < m; i++)
{
scanf("%d %d", &Q[i].l, &Q[i].r);
Q[i].id = i;
}
sort(Q, Q + m, cmp);
for (int i = ; i < m; i++)
{
while (L < Q[i].l)
Del(L++);
while (L > Q[i].l)
Add(--L);
while (R < Q[i].r)
Add(++R);
while (R > Q[i].r)
Del(R--);
ans[Q[i].id] = tot;
}
for (int i = ; i < m; i++)
{
printf("%lld\n", ans[i]);
}
}
return ;
}

hihocoder offer收割编程练习赛11 D 排队接水的更多相关文章

  1. hihocoder offer收割编程练习赛11 C 岛屿3

    思路: 并查集的应用. 实现: #include <iostream> #include <cstdio> using namespace std; ][]; int n, x ...

  2. hihocoder offer收割编程练习赛11 B 物品价值

    思路: 状态压缩 + dp. 实现: #include <iostream> #include <cstdio> #include <cstring> #inclu ...

  3. hihocoder offer收割编程练习赛11 A hiho字符串

    思路: 我用的尺取. 注意题目描述为恰好2个'h',1个'i',1个'o'. 实现: #include <iostream> #include <cstdio> #includ ...

  4. hihocoder [Offer收割]编程练习赛4

    描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...

  5. hihocoder [Offer收割]编程练习赛61

    [Offer收割]编程练习赛61 A:最小排列 给定一个长度为m的序列b[1..m],再给定一个n,求一个字典序最小的1~n的排列A,使得b是A的子序列. 贪心即可,b是A的子序列,把不在b中的元素, ...

  6. 【[Offer收割]编程练习赛11 D】排队接水

    [题目链接]:http://hihocoder.com/problemset/problem/1488 [题意] 中文题 [题解] 莫队算法+树状数组; 首先贪心地知道,应该按照时间从小到大的顺序打水 ...

  7. ACM学习历程—Hihocoder [Offer收割]编程练习赛1

    比赛链接:http://hihocoder.com/contest/hihointerview3/problem/1 大概有一个月没怎么打算法了.这一场的前一场BC,也打的不是很好.本来Div1的A和 ...

  8. hihocoder offer收割编程练习赛8 C 数组分拆

    思路:(引自bfsoyc的回答:http://hihocoder.com/discuss/question/4160) 动态规划.状态dp[i]表示 前i个数的合法的方案数,转移是 dp[i] = s ...

  9. 【[Offer收割]编程练习赛11 B】物品价值

    [题目链接]:http://hihocoder.com/problemset/problem/1486 [题意] [题解] 设f[i][j]表示前i个物品,每种属性的状态奇偶状态为j的最大价值; 这里 ...

随机推荐

  1. 深度学习笔记之目标检测算法系列(包括RCNN、Fast RCNN、Faster RCNN和SSD)

    不多说,直接上干货! 本文一系列目标检测算法:RCNN, Fast RCNN, Faster RCNN代表当下目标检测的前沿水平,在github都给出了基于Caffe的源码. •   RCNN RCN ...

  2. CAS和ABA

    1 CAS compare and swap的缩写,详见乐观锁和悲观锁. 2 ABA 就是说,我获取的旧值是A,然后被人修改成了B,但是又被人修改成了A,我就认为并没有修改,更新内存. 解决办法,给每 ...

  3. (21) java web的struts2框架的使用

    在javaweb开发过程中,如果只使用servlet,jdbc,jsp进行开发,也可以遵从MVC的模式,这时候,servlet相当于control层,属于负责处理业务逻辑的控制器,同时也需要对获取和返 ...

  4. 设计模式-(15)责任链模式 (swift版)

    一,概念: 责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行 ...

  5. 主机与虚拟机互ping

    1.设置虚拟机网络连接方式(如下图): 2.设置主机和虚拟机的ip为同一个网段,如主机ip:192.168.28.1,虚拟机ip:192.168.28.128 3.如果相互还是ping不通,就检查一下 ...

  6. 并不对劲的bzoj3932: [CQOI2015]任务查询系统

    传送门-> 离线操作听上去很简单,遗憾的是它强制在线. 每个时刻可以看成可持久化线段树中的一个版本,而每一个版本的线段树维护的是值某一段区间且在这个版本对应的时刻出现的数之和. 会发现同一时刻可 ...

  7. bzoj4289 PA2012 Tax——点边转化

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 好巧妙的转化!感觉自己难以想出来... 参考了博客:https://blog.csdn ...

  8. jenkins配置发送邮件时,日志中显示发送成功,但是邮箱没有收到邮件

    遇到这种问题,是因为安装的Email Extension Plugin插件版本与jenkins不兼容, 经试验2.39.3版本可以正常发送邮件,在jenkins主目录中 将2.39.3的文件和文件夹复 ...

  9. RestTemplate中headers中添加Host不生效

    在使用restTemplate访问内网接口时,不打算指host,支持ip访问,所以我们需要再header中指定host.但经调试,发现HttpURLConnection中Host无法覆盖.解决方案: ...

  10. bzoj 2303: [Apio2011]方格染色【并查集】

    画图可知,每一行的状态转移到下一行只有两种:奇数列不变,偶数列^1:偶数列不变,奇数列^1 所以同一行相邻的变革染色格子要放到同一个并查集里,表示这个联通块里的列是联动的 最后统计下联通块数(不包括第 ...