【[CQOI2011]动态逆序对】
这是我的第一个数据结构套数据结构
不是线段树套\(Splay\),而是非常蛇皮的块状链表套树状数组
如果这里按照\(\sqrt{n}\)的大小来分块,那么就需要\(n\sqrt{n}\)的空间,可能开不下,于是我们按照\(1000\)分块,也就只会分出\(100\)个块,就能开下空间了
之后每一次查询的时候直接查询树状数组就好了,每次修改则非常的块,直接找到对应的块改动这个块的树状数组就好了
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define lowbit(x) ((x)&(-x))
#define re register
#define maxn 100005
#define LL long long
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
int a[maxn],b[maxn];
int l[1005],r[1005],sz[1005];
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
int c[maxn];
int bit[101][maxn];
int n,m,tot,len;
LL ans;
int to[maxn],vis[maxn];
inline void add(int x)
{
for(re int i=x;i<=n;i+=lowbit(i))
c[i]++;
}
inline int ask(int x)
{
int now=0;
for(re int i=x;i;i-=lowbit(i))
now+=c[i];
return now;
}
inline void get_pair()
{
for(re int i=1;i<=n;i++)
{
ans+=ask(n)-ask(a[i]);
add(a[i]);
}
}
inline void B_add(int o,int x,int val)
{
for(re int i=x;i<=n;i+=lowbit(i)) bit[o][i]+=val;
}
inline int B_ask(int o,int x)
{
int now=0;
for(re int i=x;i;i-=lowbit(i)) now+=bit[o][i];
return now;
}
inline void build_block()
{
len=1000;
int k=1;
while(k<=n)
{
l[++tot]=k;
r[tot]=min(n,k+len-1);
k=r[tot]+1;
for(re int i=l[tot];i<=r[tot];i++)
B_add(tot,a[i],1);
}
}
inline int get_num(int x)
{
if(x%len==0) return x/len;
return x/len+1;
}
inline void BL_change(int x)
{
vis[to[x]]=1;
int now=get_num(to[x]);
B_add(now,x,-1);
}
inline int BL_find_less(int x,int y,int val)
{
int num=0;
for(re int i=x;i<=y;i++)
if(!vis[i]&&a[i]<val) num++;
return num;
}
inline int BL_find_more(int x,int y,int val)
{
int num=0;
for(re int i=x;i<=y;i++)
if(!vis[i]&&a[i]>val) num++;
return num;
}
inline int find_less(int x,int y,int val)
{
int num=0;
for(re int i=1;i<=tot;i++)
{
if(x>l[i]&&y<r[i]) return BL_find_less(x,y,val);
if(x<=l[i]&&y>=r[i]) num+=B_ask(i,val);
else if(x<=l[i]&&y<r[i]) num+=BL_find_less(l[i],y,val);
else if(y>=r[i]&&x>l[i]) num+=BL_find_less(x,r[i],val);
}
return num;
}
inline int find_more(int x,int y,int val)
{
int num=0;
for(re int i=1;i<=tot;i++)
{
if(x>l[i]&&y<r[i]) return BL_find_more(x,y,val);
if(x<=l[i]&&y>=r[i]) num+=B_ask(i,n)-B_ask(i,val);
else if(x<=l[i]&&y<r[i]) num+=BL_find_more(l[i],y,val);
else if(y>=r[i]&&x>l[i]) num+=BL_find_more(x,r[i],val);
}
return num;
}
int main()
{
n=read(),m=read();
for(re int i=1;i<=n;i++) a[i]=read(),to[a[i]]=i;
get_pair(),build_block();
int x;
while(m--)
{
printf("%lld\n",ans);
x=read();
if(to[x]!=1) ans-=find_more(1,to[x]-1,x);
if(to[x]!=n) ans-=find_less(to[x]+1,n,x);
BL_change(x);
}
return 0;
}
【[CQOI2011]动态逆序对】的更多相关文章
- BZOJ 3295: [Cqoi2011]动态逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3865 Solved: 1298[Submit][Sta ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- bzoj3295[Cqoi2011]动态逆序对 树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5987 Solved: 2080[Submit][Sta ...
- P3157 [CQOI2011]动态逆序对(树状数组套线段树)
P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...
- P3157 [CQOI2011]动态逆序对
P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...
- 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)
3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...
- [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...
- bzoj千题计划146:bzoj3295: [Cqoi2011]动态逆序对
http://www.lydsy.com/JudgeOnline/problem.php?id=3295 正着删除看做倒着添加 对答案有贡献的数对满足以下3个条件: 出现时间:i<=j 权值大小 ...
- BZOJ3295: [Cqoi2011]动态逆序对(树状数组套主席树)
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7465 Solved: 2662[Submit][Sta ...
- 洛谷 P3157 [CQOI2011]动态逆序对 解题报告
P3157 [CQOI2011]动态逆序对 题目描述 对于序列\(A\),它的逆序对数定义为满足\(i<j\),且\(A_i>A_j\)的数对\((i,j)\)的个数.给\(1\)到\(n ...
随机推荐
- java使用lock实现一个简单的生产者和消费者模式
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public ...
- linux ubuntu 学习总结(day01)基本命令学习
个人总结,请尊重版权,转载请在显眼地方注明出处:https://www.cnblogs.com/sunshine5683/p/9948259.html day(01)基本命令学习 今天开始自学linu ...
- HDU 2639(01背包第K大)
http://acm.hdu.edu.cn/showproblem.php?pid=2639 http://blog.csdn.net/lulipeng_cpp/article/details/758 ...
- java设计模式-----6、建造者模式
Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类 ...
- C#学习笔记-原型模式
题目:编写基本的简历. 实现: 创建基本的Resume类,然后主函数通过实例化Resume来写简历即可. Resume类: class Resume { private string name; pr ...
- Java注解拾遗
注解简介: 注解Annotation是jdk1.5的新增功能,在现在的日常开发中,几乎离不开注解,写篇短文,来做个拾遗. 注解作用: Annotation(注解)的作用是修饰包.类.构造方法.方法.成 ...
- POJ P3667 Hotel——solution
Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and e ...
- C#编写强大的SQL Server数据库自动备份服务
数据库自动备份服务,带配置,还算可以吧 周末抽时间,编写了一个这样的工具,可以让,对数据库不了解或不熟悉的人,直接学会使用备份,省时省力,同样,我也将一份,通过脚本进行备份的,也奉献上来, 通过sql ...
- Python 循环删除指定文件夹下所有的.longtian类型文件
# -*- coding: utf-8 -*- import os #遍历文件夹删除文件 def traversing_dir(rootDir): #遍历根目录 for root,dirs,files ...
- java中的==、equals()、hashCode()源码分析(转载)
在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. == java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...