嘛,好久没碰CDQ分治了,做道题练练手。

时间倒流——把删数改为加数。

对于每个被删的,我的想法是拆成询问和add,后来发现一个足矣。

我本来准备对每个删的数都求一遍整体逆序对,后来发现无论如何都不可做。

然后发现是只求改的逆序对,做两次CDQ,一次统计在前面大的,一次统计在后面小的。

注意:这两次的区别是id那一维的顺序不同,而time顺序是相同的。

记得离散化。

然后我打完 + 静态差错之后,一发过样例AC,稳!!!

顺手切了一模一样的3157,WA了两个点。发现输出负数......换成longlong之后AC。

 #include <cstdio>
#include <algorithm>
#include <cstring> typedef long long LL; const LL N = ; LL x[N], a[N], n; struct TreeArray {
LL tr[N];
inline void clear() {
memset(tr, , sizeof(tr));
return;
}
inline void add(LL x, LL a) {
for(; x < N; x += x & (-x)) {
tr[x] += a;
}
return;
}
inline LL getsum(LL x) {
LL ans = ;
for(; x; x -= x & (-x)) {
ans += tr[x];
}
return ans;
}
inline LL ask(LL l, LL r) {
if(l == ) {
return getsum(r);
}
return getsum(r) - getsum(l - );
}
}ta; struct Node {
LL val, ans, time, type, id;
}node[N], temp[N]; inline bool cmp_t(Node d, Node e) {
return d.time < e.time;
}
inline bool cmp__t(Node d, Node e) {
return d.time > e.time;
} void CDQ1(LL l, LL r) {
if(l == r) {
return;
}
LL mid = (l + r) >> ;
CDQ1(l, mid);
CDQ1(mid + , r); LL i = l, j = mid + , t = ;
while(i <= mid || j <= r) {
if(j > r || (i <= mid && node[i].id < node[j].id)) {
ta.add(node[i].val, );
temp[++t] = node[i++];
}
else {
if(node[j].type == ) {
node[j].ans += ta.ask(node[j].val + , n);
}
temp[++t] = node[j++];
}
}
for(i = l; i <= mid; i++) {
ta.add(node[i].val, -);
}
t = ;
for(LL i = l; i <= r; i++) {
node[i] = temp[++t];
}
return;
} void CDQ2(LL l, LL r) {
if(l == r) {
return;
}
LL mid = (l + r) >> ;
CDQ2(l, mid);
CDQ2(mid + , r); LL i = l, j = mid + , t = ;
while(i <= mid || j <= r) {
if(j > r || (i <= mid && node[i].id > node[j].id)) { /// error : id < id
ta.add(node[i].val, 1);/// error : if(type == 1)
temp[++t] = node[i++];
}
else {
if(node[j].type == ) {
node[j].ans += ta.getsum(node[j].val - );
}
temp[++t] = node[j++];
}
}
for(i = l; i <= mid; i++) {
ta.add(node[i].val, -);/// error : if(type == 1)
}
t = ;
for(i = l; i <= r; i++) {
node[i] = temp[++t];
}
return;
} LL pos[N]; int main() {
LL m;
scanf("%lld%lld", &n, &m);
for(LL i = ; i <= n; i++) {
scanf("%lld", &a[i]);
x[i] = a[i];
node[i].id = i;
node[i].type = ; /// normal
}
std::sort(x + , x + n + );
LL xx = std::unique(x + , x + n + ) - x - ;
for(LL i = ; i <= n; i++) {
LL p = std::lower_bound(x + , x + xx + , a[i]) - x;
node[i].val = p;
pos[p] = i;
}
/// li san hua wan bi LL nn = n, p;
for(LL i = ; i <= m; i++) {
scanf("%lld", &p);
p = std::lower_bound(x + , x + xx + , p) - x;
p = pos[p];
node[p].type = ; /// add
node[p].time = nn--;
}
for(LL i = ; i <= n; i++) {
if(node[i].type == ) {
node[i].time = nn--;
}
}
LL ans = ;
for(LL i = ; i <= n; i++) {
if(node[i].type == ) {
ans += ta.ask(node[i].val + , n);
ta.add(node[i].val, );
}
}
ta.clear();
std::sort(node + , node + n + , cmp_t);
CDQ1(, n);
std::sort(node + , node + n + , cmp_t); /// error : cmp__t -> cmp_t
CDQ2(, n);
std::sort(node + , node + n + , cmp__t);
for(LL i = ; i <= m; i++) {
ans += node[i].ans;
}
for(LL i = ; i <= m; i++) {
printf("%lld\n", ans);
ans -= node[i].ans;
}
return ;
}

P3157

 #include <cstdio>
#include <algorithm>
#include <cstring> const int N = ; int x[N], a[N], n; struct TreeArray {
int tr[N];
inline void clear() {
memset(tr, , sizeof(tr));
return;
}
inline void add(int x, int a) {
for(; x < N; x += x & (-x)) {
tr[x] += a;
}
return;
}
inline int getsum(int x) {
int ans = ;
for(; x; x -= x & (-x)) {
ans += tr[x];
}
return ans;
}
inline int ask(int l, int r) {
if(l == ) {
return getsum(r);
}
return getsum(r) - getsum(l - );
}
}ta; struct Node {
int val, ans, time, type, id;
}node[N], temp[N]; inline bool cmp_t(Node d, Node e) {
return d.time < e.time;
}
inline bool cmp__t(Node d, Node e) {
return d.time > e.time;
} void CDQ1(int l, int r) {
if(l == r) {
return;
}
int mid = (l + r) >> ;
CDQ1(l, mid);
CDQ1(mid + , r); int i = l, j = mid + , t = ;
while(i <= mid || j <= r) {
if(j > r || (i <= mid && node[i].id < node[j].id)) {
ta.add(node[i].val, );
temp[++t] = node[i++];
}
else {
if(node[j].type == ) {
node[j].ans += ta.ask(node[j].val + , n);
}
temp[++t] = node[j++];
}
}
for(i = l; i <= mid; i++) {
ta.add(node[i].val, -);
}
t = ;
for(int i = l; i <= r; i++) {
node[i] = temp[++t];
}
return;
} void CDQ2(int l, int r) {
if(l == r) {
return;
}
int mid = (l + r) >> ;
CDQ2(l, mid);
CDQ2(mid + , r); int i = l, j = mid + , t = ;
while(i <= mid || j <= r) {
if(j > r || (i <= mid && node[i].id > node[j].id)) {
ta.add(node[i].val, );
temp[++t] = node[i++];
}
else {
if(node[j].type == ) {
node[j].ans += ta.getsum(node[j].val - );
}
temp[++t] = node[j++];
}
}
for(i = l; i <= mid; i++) {
ta.add(node[i].val, -);
}
t = ;
for(i = l; i <= r; i++) {
node[i] = temp[++t];
}
return;
} int main() {
int m;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
x[i] = a[i];
node[i].id = i;
node[i].type = ; /// normal
}
std::sort(x + , x + n + );
int xx = std::unique(x + , x + n + ) - x - ;
for(int i = ; i <= n; i++) {
int p = std::lower_bound(x + , x + xx + , a[i]) - x;
node[i].val = p;
}
/// li san hua wan bi int nn = n;
for(int i = ; i <= m; i++) {
scanf("%d", &xx);
node[xx].type = ; /// add
node[xx].time = nn--;
}
for(int i = ; i <= n; i++) {
if(node[i].type == ) {
node[i].time = nn--;
}
}
int ans = ;
for(int i = ; i <= n; i++) {
if(node[i].type == ) {
ans += ta.ask(node[i].val + , n);
ta.add(node[i].val, );
}
}
ta.clear();
std::sort(node + , node + n + , cmp_t);
CDQ1(, n);
std::sort(node + , node + n + , cmp_t);
CDQ2(, n);
std::sort(node + , node + n + , cmp__t);
for(int i = ; i <= m; i++) {
ans += node[i].ans;
}
for(int i = ; i <= m + ; i++) {
printf("%d ", ans);
ans -= node[i].ans;
}
return ;
}

P1393

CDQ大法好!

洛谷 P1393 P3157 动态逆序对的更多相关文章

  1. P3157 动态逆序对 CDQ分治

    动态逆序对 CDQ分治 传送门:https://www.luogu.org/problemnew/show/P3157 题意: 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对 ...

  2. 洛谷P3157 动态逆序对 [CQOI2011] cdq分治

    正解:cdq分治 解题报告: 传送门! 长得有点像双倍经验还麻油仔细看先放上来QwQ! 这题首先想到的就直接做逆序对,然后记录每个点的贡献,删去就减掉就好 但是仔细一想会发现布星啊,如果有一对逆序对的 ...

  3. 【洛谷 P2513】 [HAOI2009]逆序对数列(DP)

    题目链接 这种求方案数的题一般都是\(dp\)吧. 注意到范围里\(k\)和\(n\)的范围一样大,\(k\)是完全可以更大的,到\(n\)的平方级别,所以这暗示了我们要把\(k\)写到状态里. \( ...

  4. 洛谷 P4280 bzoj1786 [AHOI2008]逆序对(dp)

    题面 luogu bzoj 题目大意: 给你一个长度为\(n\)的序列,元素都在\(1-k\)之间,有些是\(-1\),让你把\(-1\)也变成\(1-k\)之间的数,使得逆序对最多,求逆序对最少是多 ...

  5. 洛谷P1966 火柴排队(逆序对)

    题意 题目链接 Sol 不算很难的一道题 首先要保证权值最小,不难想到一种贪心策略,即把两个序列中rank相同的数放到同一个位置 证明也比较trivial.假设\(A\)中有两个元素\(a, b\), ...

  6. 洛谷【P1908】逆序对

    题目传送门:https://www.luogu.org/problemnew/show/P1908 所谓逆序对,就是序列中\(a[i]>a[j]\)且\(i<j\)的有序对. 所以我们在归 ...

  7. 【Luogu】P3157动态逆序对(树状数组套主席树)

    题目链接 md第一道在NOILinux 下用vim做的紫题.由于我对这个操作系统不是很熟悉,似乎有什么地方搞错了,md调死.(我还打了两遍代码,调了两个小时) 但是这道题并不难,就是树状数组套上主席树 ...

  8. 洛谷 题解 P1908 【逆序对】

    一开始竟然妄想用\(n^2\)的算法过这题,然而这是不可能的 所以只好写归并排序来求逆序対惹 比如将下面两个区间排序 3 4 7 9 1 5 8 10 首先将右区间的\(1\)取出,放到\(r_k\) ...

  9. bzoj3295 洛谷P3157、1393 动态逆序对——树套树

    题目:bzoj3295 https://www.lydsy.com/JudgeOnline/problem.php?id=3295 洛谷 P3157(同一道题) https://www.luogu.o ...

随机推荐

  1. NFS配置与搭建

    参考: Linux下NFS服务器的搭建与配置 https://www.cnblogs.com/liuyisai/p/5992511.html http://blog.51cto.com/hongten ...

  2. mysql “Too many connections” 解决办法

    今天生产服务器上的MySQL出现了一个不算太陌生的错误“Too many connections”.平常碰到这个问题,我基本上是修改/etc/my.cnf的max_connections参数,然后重启 ...

  3. Delphi处理数据网格DBGrid的编辑框 获取还没有提交到数据集的字段文本

    //fromhttp://kingron.myetang.com/zsfunc12.htm (*//标题:处理数据网格的编辑框说明:示例添加焦点颜色;获取还没有提交到数据集的字段文本设计:Zswang ...

  4. ExportHandler.ashx

    using KYZWeb.Common;using Liger.Data;//using Microsoft.Office.Interop.Excel;using System;using Syste ...

  5. WPF中如何调整TabControl的大小,使其跟随Window的大小而改变?

    多年不写技术博客,手生的很,也不知道大家都关注什么,最近在研究Wpf及3d模型的展示,碰到很多问题,这个是最后一个问题,写出来小结一下...... WPF中如何调整TabControl的大小,使其跟随 ...

  6. 思路:controller层:后台如何取值 前端如何给name赋值 例如是id赋值还是自己随意定义

    思路:controller层:后台如何取值 前端如何给name赋值 例如是id赋值还是自己随意定义

  7. codeforces545C

    Woodcutters CodeForces - 545C Little Susie listens to fairy tales before bed every day. Today's fair ...

  8. Centos安装python3

    安装环境 系统:阿里云服务器centos7.5系统 看见好多博客对centos安装python3的方式各不相同且都不完整,今天我来完整的演示安装python3 1.下载python3源码包 命令 wg ...

  9. 实现纯英文string的逆序输出

      第一种方法: using namespace std; void Reverse(string &a) { int n = a.size(); char b; ;i<n/;i++) ...

  10. python 脚本之 IP地址探测

    #第一种方法#!/usr/bin/env python #_*_ coding:utf8 _*_ #### 该脚本需要使用fping命令 如果没有安装需要提前安装fping #### yum inst ...