题目大意:有一串数为$1\sim n(n\leqslant2\times10^5)$,$m(m\leqslant5\times10^4)$次询问,每次问交换位置为$l,r$的两个数后数列中逆序对的个数。

题解:发现交换位置为$l,r$的数后,逆序对的变化只和区间$(l,r)$内的数与$s_l,s_r$的大小关系有关,设$S_i$表示区间$(l,r)$中比$s_i$小的数,$B_i$表示区间$(l,r)$中比$s_i$大的数,$ans'=ans+S_r-B_r-S_l+B_l$。设$len=r-l-1$,$ans'=ans+S_r-(len-S_r)-S_l+(len-S_l)=ans+2(S_r-S_l)$。

考虑分块,设块大小为$S$,在块内排序,在边角处暴力,在整块处二分查找位置,询问的复杂度是$O(2S+\dfrac n S\log_2S)$;修改为二分处位置直接插入或删除,复杂度$O(4S)$,所以当$S$略大于$\sqrt n$时最优。(反正我懒得算,随便猜一个)

卡点:

  1. 计算$2(S_r-S_l)$时使用了位运算,当$S_r-S_l$为负数时出锅
  2. 最开始块大小设成了$512$,计算块时用了$2^8$

C++ Code:

#include <algorithm>
#include <cstdio>
#include <vector>
#define maxn 200010
const int BSZ = 1000, BNUM = maxn / BSZ + 10; int n, m;
long long ans;
int L[BNUM], R[BNUM], bel[maxn], s[maxn];
std::vector<int> V[BNUM]; int query(int l, int r, int x) {
if (l > r) return 0;
const int lb = bel[l], rb = bel[r];
int res = 0;
if (lb == rb) for (int i = l; i <= r; ++i) res += s[i] < x;
else {
for (int i = l; i <= R[lb]; ++i) res += s[i] < x;
for (int i = lb + 1; i < rb; ++i) res += std::upper_bound(V[i].begin(), V[i].end(), x) - V[i].begin();
for (int i = L[rb]; i <= r; ++i) res += s[i] < x;
}
return res;
} int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) V[bel[i] = i / BSZ + 1].push_back(s[i] = i);
const int B = bel[n];
for (int i = 1; i <= B; ++i) {
L[i] = (i - 1) * BSZ;
R[i] = L[i] + BSZ - 1;
}
L[1] = 1, R[B] = n;
while (m --> 0) {
int l, r;
scanf("%d%d", &l, &r);
if (l == r) {
printf("%lld\n", ans);
continue;
}
if (l > r) std::swap(l, r);
const int lb = bel[l], rb = bel[r]; ans += (query(l + 1, r - 1, s[r]) - query(l + 1, r - 1, s[l])) * 2;
ans += (s[l] < s[r]) ? 1 : -1;
printf("%lld\n", ans); if (lb != rb) {
V[lb].erase(std::lower_bound(V[lb].begin(), V[lb].end(), s[l]));
V[lb].insert(std::upper_bound(V[lb].begin(), V[lb].end(), s[r]), s[r]);
V[rb].erase(std::lower_bound(V[rb].begin(), V[rb].end(), s[r]));
V[rb].insert(std::upper_bound(V[rb].begin(), V[rb].end(), s[l]), s[l]);
}
std::swap(s[l], s[r]);
}
return 0;
}

  

[CF785E]Anton and Permutation的更多相关文章

  1. Codeforces785E - Anton and Permutation

    Portal Description 对一个长度为\(n(n\leq2\times10^5)\)的数列\(a\)进行\(m(m\leq5\times10^4)\)次操作,数列初始时为\(\{1,2,. ...

  2. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

  3. Anton and Permutation

    Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input standa ...

  4. Codeforces 785 E. Anton and Permutation(分块,树状数组)

    Codeforces 785 E. Anton and Permutation 题目大意:给出n,q.n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询.每次查询给出两个数l,r,要求 ...

  5. 题解 CF785E 【Anton and Permutation】

    考虑用分块解决这个题,一次交换对当前逆序对个数的影响是,加上两倍的在区间\([l+1,r-1]\)中比\(a_r\)小的元素个数,减去两倍的在区间\([l+1,r-1]\)中比\(a_l\)小的元素个 ...

  6. Codeforces 785E. Anton and Permutation

    题目链接:http://codeforces.com/problemset/problem/785/E 其实可以CDQ分治... 我们只要用一个数据结构支持单点修改,区间查询比一个数大(小)的数字有多 ...

  7. Codeforces 785E Anton and Permutation(分块)

    [题目链接] http://codeforces.com/contest/785/problem/E [题目大意] 一个1到n顺序排列的数列,每次选择两个位置的数进行交换,求交换后的数列的逆序对数 [ ...

  8. CodeForces 785E Anton and Permutation 分块

    题意: 有一个\(1 \sim n\)的排列\(A\),有\(q\)个询问: 交换任意两个元素的位置,求交换之后排列的逆序数 分析: 像这种不太容易用线段树,树状数组维护的可以考虑分块 每\(\sqr ...

  9. 【codeforces 785E】Anton and Permutation

    [题目链接]:http://codeforces.com/problemset/problem/785/E [题意] 给你一个初始序列1..n顺序 然后每次让你交换任意两个位置上面的数字; 让你实时输 ...

随机推荐

  1. hive中的优化问题

    一.fetch抓取 fetch 抓取是指,hive中对某些情况的查询可以不必使用MapReduce计算.(1)把hive.fetch.task.conversion 设置成none,然后执行查询语句, ...

  2. 修改Eclipse中项目在Apache Tomcat中的部署路径

    在Eclipse中配项目已经部署到如下默认目录下:eclipse workspace/.metadata/.plugins/org.eclipse.core.resources/.projects. ...

  3. HTML 常见的 DOCTYPE 声明

    <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. <!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关 ...

  4. Python3安装pywin32模块

    假如你安装的是Python3.6, 那么可以直接用PyCharm或者pip安装pywin32模块: 但是, 由于我安装的是Python3.7, 所以PyCharm或者pip都无法成功安装pywin32 ...

  5. Linux命令应用大词典-第5章 显示文本和文件内容

    5.1 cat:显示文本文件 5.2 more:分页显示文本文件 5.3 less:回卷显示文本文件 5.4 head:显示指定文件前若干行 5.5 tail:查看文件末尾数据 5.6 nl:显示文件 ...

  6. 转:vue生命周期流程图

  7. CSP201509-2:日期计算

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  8. HDU 2489 Minimal Ratio Tree(暴力+最小生成树)(2008 Asia Regional Beijing)

    Description For a tree, which nodes and edges are all weighted, the ratio of it is calculated accord ...

  9. 【web前端开发】浏览器兼容性处理大全

    1.居中问题 div里的内容,IE默认为居中,而FF默认为左对齐,可以尝试增加代码margin: 0 auto; 2.高度问题 两上下排列或嵌套的div,上面的div设置高度(height),如果di ...

  10. iOS- Apple零配置网络协议Bonjour的使用?

    1.前言 这段时间为了解决公司App的网络离线需求,做了个Apple推出的零配置网络协议Bonjour的Test,主要是为了解决iOS设备的IP获取,之前是可以使用socket的广播来实现,但是使用A ...