题目描述

给定一个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. Python3基础 逻辑与 and

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  2. 无法为表空间 XX 中的段创建 INITIAL 区

    select * from dba_data_files where TABLESPACE_NAME='XX'--找到表空间文件 alter database datafile '/opt/app/o ...

  3. Create Hierarchical Tree To Control Records In Oracle Forms

    Download Source Code Providing an example form for creating hierarchical trees in Oracle Forms to co ...

  4. CUBRID学习笔记 38 net调用java的函数过程

    首先要设置java_stored_procedure 为yes  该配置项在cubrid.conf中 书写并编译java代码 public class SpCubrid{      public st ...

  5. Java——Image 图片切割

    package com.tb.image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io ...

  6. const变量赋值报错分析

    const变量赋值报错分析 const变量赋值报错 从变量到常量的赋值是合法C++的语法约定的, 如从char 到const char顺畅: 但从char **到 const char **编译器就会 ...

  7. installing a 3D printer

    托公司的福,今天可以自己组装一台3D打印机.心里颇有一种开箱有益的兴奋. 落入手中的是一台Panowin F1,价格不贵,却同时拥有了3D打印功能和激光打印功能.颇有一种小型创客作坊的雏形. 硬件搭建 ...

  8. XPah学习

    资料1: 来源:http://www.cnblogs.com/ChengDong/archive/2012/06/28/2567744.html 示例Xml: <?xml version=&qu ...

  9. 高效使用Vector

    参考网页: http://www.cnblogs.com/biyeymyhjob/archive/2013/05/11/3072893.html#undefined 1.初始化的时候,最好先用rese ...

  10. STL--set

    set-概述: 集合Set是一个容器,它其中所包含的元素的值是唯一的.集合中的元素按一定的顺序排列,并被作为集合中的实例. 一个集合通过一个链表来组织,其具体实现采用了红黑树的平衡二叉树的数据结构. ...