首页 技术 正文
技术 2022年11月15日
0 收藏 603 点赞 4,169 浏览 2070 个字

3289: Mato的文件管理

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 2368  Solved: 971
[Submit][Status][Discuss]

Description

Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号。为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问。Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料。Mato有一个习惯,他总是从文件大小从小到大看资料。他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序。排序程序可以在1单位时间内交换2个相邻的文件(因为加密需要,不能随机访问)。Mato想要使文件交换次数最小,你能告诉他每天需要交换多少次吗?

Input

第一行一个正整数n,表示Mato的资料份数。
第二行由空格隔开的n个正整数,第i个表示编号为i的资料的大小。
第三行一个正整数q,表示Mato会看几天资料。
之后q行每行两个正整数l、r,表示Mato这天看[l,r]区间的文件。

Output

q行,每行一个正整数,表示Mato这天需要交换的次数。

Sample Input

4
1 4 2 3
2
1 2
2 4

Sample Output

0
2

HINT

Hint

n,q <= 50000

样例解释:第一天,Mato不需要交换

第二天,Mato可以把2号交换2次移到最后。

Source

By taorunz

[Submit][Status][Discuss]

小生的第二道莫队算法。易知一段区间内的最小交换次数就是这段区间内的逆序对数,这个可以通过用树状数组动态维护。树状数组是按权值组织的,当在区间右侧新加入一个元素时,新形成的逆序对数就是前面区间中严格大于该元素的元素个数,反之亦然,请客官自行推导吧(ノ*・ω・)ノ。

 #include <bits/stdc++.h> template <class T>
inline void read(T &num) {
register int neg = false;
register int bit = getchar(); while (bit <= '') {
if (bit == '-')
neg ^= neg;
bit = getchar();
} num = ; while (bit >= '') {
num = num*
+ bit - '';
bit = getchar();
} if (neg)num = -num;
} const int siz = ; int n, m, s, num[siz], tmp[siz], bit[siz], answer; struct query {
int l, r, id, ans;
}qry[siz]; inline bool cmp_lr(const query &A, const query &B) {
if (A.l / s != B.l / s)
return A.l < B.l;
else
return A.r < B.r;
} inline bool cmp_id(const query &A, const query &B) {
return A.id < B.id;
} inline void add(int k, int v) {
for (; k <= n; k += k&-k)bit[k] += v;
} inline int ask(int k) {
int ret = ;
for (; k >= ; k -= k&-k)ret += bit[k];
return ret;
} signed main(void) {
read(n); for (int i = ; i <= n; ++i)
read(num[i]); memcpy(tmp, num, sizeof(tmp)); std::sort(tmp + , tmp + + n); int tot = std::unique(tmp + , tmp + + n) - tmp; for (int i = ; i <= n; ++i)
num[i] = std::lower_bound(tmp, tmp + tot, num[i]) - tmp; read(m); for (int i = ; i <= m; ++i)
read(qry[i].l), read(qry[i].r), qry[i].id = i; s = sqrt(n); std::sort(qry + , qry + + m, cmp_lr); for (int i = , x = , y = ; i <= m; ++i) {
while (x < qry[i].l)answer -= ask(num[x] - ), add(num[x], -), ++x;
while (x > qry[i].l)--x, answer += ask(num[x] - ), add(num[x], +);
while (y < qry[i].r)++y, answer += ask(n) - ask(num[y]), add(num[y], +);
while (y > qry[i].r)answer -= ask(n) - ask(num[y]), add(num[y], -), --y;
qry[i].ans = answer;
} std::sort(qry + , qry + + m, cmp_id); for (int i = ; i <= m; ++i)
printf("%d\n", qry[i].ans);
}

@Author: YouSiki

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,581
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918