题目大意:有一串数为$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. ORB-SLAM(八)ORBmatcher 特征匹配

    该类负责特征点与特征点之间,地图点与特征点之间通过投影关系.词袋模型或者Sim3位姿匹配.用来辅助完成单目初始化,三角化恢复新的地图点,tracking,relocalization以及loop cl ...

  2. SpspringBoot日志logback-spring.xml分环境

    SpspringBoot日志logback-spring.xml分环境 2017年08月02日 03:05:13 cqqianyi1 阅读数:30563 标签: logback slf4j sprin ...

  3. EWS3-24S05电源转换芯片DC-DC

    1. EWS3-24S05是24V转5V的DC-DC电源,输入和输出都是直流电. 2. 典型应用 3. 引脚图 4. 使用注意事项: 输入电源的要求 输入电源的要求产品的输入端必需接一个低阻抗的电压源 ...

  4. C# 组装XML传给webserver+XML 返回获取多个xml,根据多个XML 返回dataset类型

    大致流程介绍: 传值给 webserver+XML ,得到webserver+XML多个返回值,组装成dataset形式返回 首先创建所需要的类型 DataSet ds = new DataSet() ...

  5. 「日常训练」Balancing Act(POJ-1655)

    题意与分析 树的重心板子题. 值得考虑的是,重心究竟有哪些优秀的性质? 这里是一些网上能看到的性质: (判定性质)找到一个点,其所有的子树中最大的子树节点数最少(子树可以"倒着看" ...

  6. 「日常训练」COMMON 约数研究(HYSBZ-1968)

    题意与分析 感谢https://www.cnblogs.com/Leohh/p/7512960.html的题解.这题话说原来不在我的训练范围,正好有个同学问我,我就拿来做做.数学果然不是我擅长的啊,这 ...

  7. Objective-C 构造方法 分类 类的深入研究

    构造方法 1.对象创建的原理 new的拆分两部曲 Person *p = [Person alloc]; 分配内存(+alloc) Person *p = [p init]; 初始化(-init) 合 ...

  8. 记一次Log4j2日志无法输出的 心酸史

    问题描述:部分日志无法输出到日志文件中. 项目中的代码: @Resource private ConfigInfo configInfo; private static final Logger lo ...

  9. IntelliJ IDEA 2017.3/2018.1/.2 激活

    传统的License Server方式已经无法注册IntelliJ IDEA2017.3的版本了. http://idea.lanyus.com,这个网站有破解补丁和注册码两种方式,另外http:// ...

  10. Struts2中Action各种转发类型

    Struts2:Action中result的各种转发类型: 内部请求转发dispatcher(默认值) redirect.redirectAction.plainText1.redirect是重定向到 ...