题目描述

给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数。

分析:分块+树状数组

(PS:本题的CDQ分治解法见下一篇)

首先将序列分成T块,每一块开一个树状数组,并且先把最初的答案统计完成。

对于每一次删除,找到对应位置,考虑删除之后的增减情况:

①块内:直接暴力,对于左边,少了比它大的个数,对于右边,少了比它小的个数,

②块外:枚举每一块。对于左边,少了比它大的个数,对于右边,少了比它小的个数,。

然后把这个位置的数分别从数组和树状数组中删除,。

为了最小化时间,我们使,忽略,所以取即可。

小结

一些自己不容易出错的写法:

①本题数组使用*a的方法

②涉及lint,须检验 参数声明、变量声明、函数声明、输入输出

③同一行最多只能有一类函数,且不要与其他运算,否则使用tmp

④分块的问题,直接将块的大小设为确定值,并标记块的个数上限,还有就是(i-1)/unit+1的写法

⑤对于一个参数,如果需要作空间且需要枚举,若数值上的差>1,那么开两个参数

⑥对于一个整数a判断是否大于0,写作a>0,不要写作a

代码

#include <cstdio>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;

typedef long long lint;

const int N=100010;
const int BLOCK_SIZE=1000;
const int BLOCK_NUM=101;

int n,m;

int a[N];
int loc[N];

lint t[N];
lint res;

int num;
lint tr[BLOCK_NUM][N];

inline int read(void)
{
    int x=0; char c=getchar();
    for (;!isdigit(c);c=getchar());
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x;
}

inline int lowbit(int i)
{
    return i&-i;
}

inline void ins(lint *ta,int i,int add)
{
    for (;i<=n;i+=lowbit(i)) ta[i]+=add;
}

inline lint query(lint *ta,int i)
{
    lint sum=0;
    for (;i;i-=lowbit(i)) sum+=ta[i];
    return sum;
}

inline void update(int x)
{
    int loca=loc[x],bel=(loca-1)/BLOCK_SIZE+1;

    for (int i=BLOCK_SIZE*(bel-1)+1;i<loca;i++)
        if (a[i]>0&&a[i]>x) res--;
    for (int i=loca+1;i<=min(BLOCK_SIZE*bel,n);i++)
        if (a[i]>0&&a[i]<x) res--;

    lint tmp;
    for (int i=1;i<bel;i++)
    {
        tmp=query(tr[i],n)-query(tr[i],x-1);
        res-=tmp;
    }
    for (int i=bel+1;i<=num;i++)
    {
        tmp=query(tr[i],x-1);
        res-=tmp;
    }

    a[loca]=0;
    ins(tr[bel],x,-1);
}

int main(void)
{
//  freopen("a.in","r",stdin);
//  freopen("a.out","w",stdout);

    n=read(),m=read();

    for (int i=1;i<=n;i++) a[i]=read();
    for (int i=1;i<=n;i++) loc[a[i]]=i;

    lint tmp;
    for (int i=n;i>=1;i--)
    {
        tmp=query(t,a[i]);
        res=res+tmp;
        ins(t,a[i],1);
    }

    int belo;
    num=(n-1)/BLOCK_SIZE+1;
    for (int i=1;i<=n;i++)
    {
        belo=(i-1)/BLOCK_SIZE+1;
        ins(tr[belo],a[i],1);
    }

    for (int i=1;i<=m;i++)
    {
        printf("%lld\n",res);
        update(read());
    }

    return 0;
}

【BZOJ 3295】动态逆序对 - 分块+树状数组的更多相关文章

  1. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  2. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  3. BZOJ3295: [Cqoi2011]动态逆序对(树状数组套主席树)

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7465  Solved: 2662[Submit][Sta ...

  4. BZOJ3295 动态逆序对(树状数组套线段树)

    [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6058  Solved: 2117[Submit][Status][D ...

  5. bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组

    [bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...

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

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

  7. BZOJ3295 [Cqoi2011]动态逆序对 分治 树状数组

    原文链接http://www.cnblogs.com/zhouzhendong/p/8678185.html 题目传送门 - BZOJ3295 题意 对于序列$A$,它的逆序对数定义为满足$i< ...

  8. BZOJ 3295 动态逆序对 | CDQ分治

    BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...

  9. AcWing 107. 超快速排序(归并排序 + 逆序对 or 树状数组)

    在这个问题中,您必须分析特定的排序算法----超快速排序. 该算法通过交换两个相邻的序列元素来处理n个不同整数的序列,直到序列按升序排序. 对于输入序列9 1 0 5 4,超快速排序生成输出0 1 4 ...

随机推荐

  1. 命令行下运行php的方法和技巧

    linux中直接用"php"命令来执行php文件 一般在linux命令行下运行php文件的代码: XML/HTML代码 linux下执行:#php安装路径 -f php文件路径 例 ...

  2. CentOS 6.3下源码安装LAMP(Linux+Apache+Mysql+Php)环境

    一.简介 什么是LAMP    LAMP是一种Web网络应用和开发环境,是Linux, Apache, MySQL, Php/Perl的缩写,每一个字母代表了一个组件,每个组件就其本身而言都是在它所代 ...

  3. 零零碎碎写的shell脚本(二):一键修改网络配置信息脚本

    #!/bin/bash ip_mod=$ mask_mod=$ gw_mod=$ dns_mod=$ hostname_mod=$ hosts=/etc/hosts ifcfg=/etc/syscon ...

  4. Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨

    Java对象克隆(Clone)及Cloneable接口.Serializable接口的深入探讨 Part I 没啥好说的,直接开始Part II吧. Part II 谈到了对象的克隆,就不得不说为什么 ...

  5. 在Linux命令行下令人惊叹的惊叹号(!)

    '!'符号在Linux中不但可以用作否定符号,还可以用来从历史命令记录中取出命令或不加修改的执行之前运行的命令.下面的所有命令都已经在Bash Shell中经过确切地检验.尽管我没有试过,但大多都不能 ...

  6. 我的android学习经历22

    eclipse自动退出 今天打开eclipse的时候出现自动退出,也就是打不开了 我上网查了一下,把工作区间改了一下就好了 修改默认工作区间的如下:(不是默认的话直接修改就好) eclipse\con ...

  7. <转>离婚前夜悟出的三件事

    文/铁眼(简书作者)原文链接:http://www.jianshu.com/p/832be4f659a0?utm_campaign=hugo&utm_medium=reader_share&a ...

  8. 3d中的坐标系的概念

    世界坐标系 世界坐标系是一个特殊的坐标系,它建立了描述其它坐标系所需要的参考框架.从另一方面说能够用世界坐标描述其它坐标系的位置,而不能用更大的.外部的坐标系来描述世界坐标系. 物体坐标系 物体坐标系 ...

  9. Windows Live Writer代码高亮插件对比

    一.Paste ASVisual Studio Code 参考:http://www.cnblogs.com/mikelij/archive/2010/11/13/1876199.html 插件下载: ...

  10. Bson

    https://en.wikipedia.org/wiki/BSON BSON /ˈbiːsɒn/ is a computer data interchange format used mainly ...