(又是一道树套树……自己真是玩疯了……)

(题意略)

从网上也看过题解,好像解法很多……比如CDQ+树状数组,树状数组套主席树,树状数组套平衡树……我用的是树状数组套splay。

(我会说是因为我不会写CDQ和树状数组套主席树么= =)

(不得不吐槽,为啥splay这么快= =)

也没啥可说的,我写的是在线算法,只要在删除一个元素之前统计它前面比它大的数和后面比它小的数的个数(区间求和用树状数组,统计比它小/大的数的个数用平衡树写),把答案减掉对应数值即可。

鉴于这题卡常,我就加了快读和各种inline卡常大法,然后卡了不下5次评测机才过……(COGS垃圾评测机)

顺便一提,求初始逆序对可以用归并排序or树状数组,我用的是后者。

贴个代码(貌似这是全程非递归):

#include<cstdio>
#include<cstring>
#include<algorithm>
#define siz(x) ((x)?(x)->size:0)
#define lowbit(x) ((x)&(-(x)))
using namespace std;
namespace mine{
template<class T>inline void readint(T &__x){
static int __c;
static bool __neg;
__x=;
__neg=false;
do __c=getchar();while(__c==' '||__c=='\n'||__c=='\r'||__c=='\t');
if(__c=='-'){
__neg=true;
__c=getchar();
}
for(;__c>=''&&__c<='';__c=getchar())__x=__x*+(__c^);
if(__neg)__x=-__x;
}
template<class T>inline void putint(T __x){
static int __a[],__i,__j;
static bool __neg;
__neg=__x<;
if(__neg)__x=-__x;
__i=;
do{
__a[__i++]=__x%(T)^(T);
__x/=;
}while(__x);
if(__neg)putchar('-');
for(__j=__i-;__j^-;__j--)putchar(__a[__j]);
}
}
using namespace mine;
const int maxn=;
struct node{//Splay Tree
int data,size;
node *lc,*rc,*prt;
node(int d=):data(d),size(),lc(NULL),rc(NULL),prt(NULL){}
inline void refresh(){size=siz(lc)+siz(rc)+;}
}*root[maxn]={NULL};
void add(int);
void query(int);
void build(int,int);
int qlss(int,int);
int qgrt(int,int);
void mdel(int,int);
void insert(node*,int);
node *find(int,int);
void erase(node*,int);
int rank(int,int);
int rerank(int,int);
void splay(node*,node*,int);
void lrot(node*,int);
void rrot(node*,int);
node *findmax(node*);
int n,m,a[maxn],b[maxn],c[maxn]={},x;
long long ans=0ll;
int main(){
#define MINE
#ifdef MINE
freopen("inverse.in","r",stdin);
freopen("inverse.out","w",stdout);
#endif
readint(n);
readint(m);
for(int i=;i<=n;i++){
readint(a[i]);
b[a[i]]=i;
query(a[i]);
add(a[i]);
build(i,a[i]);
}
while(m--){
putint(ans);
putchar('\n');
readint(x);
x=b[x];
ans-=(long long)qgrt(x,a[x])+(long long)qlss(n,a[x])-(long long)qlss(x-,a[x]);
mdel(x,a[x]);
}
#ifndef MINE
printf("\n--------------------DONE--------------------\n");
for(;;);
#endif
return ;
}
inline void add(int x){
while(x){
c[x]++;
x-=lowbit(x);
}
}
inline void query(int x){
while(x<=n){
ans+=c[x];
x+=lowbit(x);
}
}
inline void build(int x,int d){
while(x<=n){
insert(new node(d),x);
x+=lowbit(x);
}
}
inline int qlss(int x,int d){
int ans=;
while(x){
ans+=rank(d,x);
x-=lowbit(x);
}
return ans;
}
inline int qgrt(int x,int d){
int ans=;
while(x){
ans+=rerank(d,x);
x-=lowbit(x);
}
return ans;
}
inline void mdel(int x,int d){
while(x<=n){
erase(find(d,x),x);
x+=lowbit(x);
}
}
inline void insert(node *x,int i){
if(!root[i]){
root[i]=x;
return;
}
node *rt=root[i];
for(;;){
if(x->data<rt->data){
if(rt->lc)rt=rt->lc;
else{
rt->lc=x;
break;
}
}
else{
if(rt->rc)rt=rt->rc;
else{
rt->rc=x;
break;
}
}
}
x->prt=rt;
for(;rt;rt=rt->prt)rt->refresh();
splay(x,NULL,i);
}
inline node *find(int x,int i){
node *rt=root[i];
while(rt){
if(x==rt->data)return rt;
else if(x<rt->data)rt=rt->lc;
else rt=rt->rc;
}
return NULL;
}
inline void erase(node *x,int i){
splay(x,NULL,i);
if(x->lc){
splay(findmax(x->lc),x,i);
x->lc->rc=x->rc;
if(x->rc)x->rc->prt=x->lc;
x->lc->prt=NULL;
root[i]=x->lc;
x->lc->refresh();
}
else{
if(x->rc)x->rc->prt=NULL;
root[i]=x->rc;
}
delete x;
}
inline int rank(int x,int i){
node *rt=root[i],*y=NULL;
int ans=;
while(rt){
y=rt;
if(x<=rt->data)rt=rt->lc;
else{
ans+=siz(rt->lc)+;
rt=rt->rc;
}
}
if(y)splay(y,NULL,i);
return ans;
}
inline int rerank(int x,int i){
return siz(root[i])-rank(x+,i);
}
inline void splay(node *x,node *tar,int i){
for(node *rt=x->prt;rt!=tar;rt=x->prt){
if(rt->prt==tar){
if(x==rt->lc)rrot(rt,i);
else lrot(rt,i);
break;
}
if(rt==rt->prt->lc){
if(x==rt->lc)rrot(rt,i);
else lrot(rt,i);
rrot(x->prt,i);
}
else{
if(x==rt->rc)lrot(rt,i);
else rrot(rt,i);
lrot(x->prt,i);
}
}
}
inline void lrot(node *x,int i){
node *y=x->rc;
if(x->prt){
if(x==x->prt->lc)x->prt->lc=y;
else x->prt->rc=y;
}
else root[i]=y;
y->prt=x->prt;
x->rc=y->lc;
if(y->lc)y->lc->prt=x;
y->lc=x;
x->prt=y;
x->refresh();
y->refresh();
}
inline void rrot(node *x,int i){
node *y=x->lc;
if(x->prt){
if(x==x->prt->lc)x->prt->lc=y;
else x->prt->rc=y;
}
else root[i]=y;
y->prt=x->prt;
x->lc=y->rc;
if(y->rc)y->rc->prt=x;
y->rc=x;
x->prt=y;
x->refresh();
y->refresh();
}
inline node *findmax(node *x){
while(x->rc)x=x->rc;
return x;
}

[CQOI2011]动态逆序对的更多相关文章

  1. BZOJ 3295: [Cqoi2011]动态逆序对

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

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

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

  3. bzoj3295[Cqoi2011]动态逆序对 树套树

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

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

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

  5. P3157 [CQOI2011]动态逆序对

    P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...

  6. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

    3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...

  7. [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...

  8. bzoj千题计划146:bzoj3295: [Cqoi2011]动态逆序对

    http://www.lydsy.com/JudgeOnline/problem.php?id=3295 正着删除看做倒着添加 对答案有贡献的数对满足以下3个条件: 出现时间:i<=j 权值大小 ...

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

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

  10. 洛谷 P3157 [CQOI2011]动态逆序对 解题报告

    P3157 [CQOI2011]动态逆序对 题目描述 对于序列\(A\),它的逆序对数定义为满足\(i<j\),且\(A_i>A_j\)的数对\((i,j)\)的个数.给\(1\)到\(n ...

随机推荐

  1. ubuntu下怎么解决python "Non-ASCII character"错误

    解决方法:源代码文件第一行添加:#coding:utf-8 参考:  http://jingyan.baidu.com/album/219f4bf7d04887de442d3899.html?pici ...

  2. Spring利用JDBCTemplate实现批量插入和返回id

    1.先介绍一下java.sql.Connection接口提供的三个在执行插入语句后可取的自动生成的主键的方法: //第一个是 PreparedStatement prepareStatement(St ...

  3. Redis 分布式session

    这里有三种和方式实现: 1.Harbour.RedisSessionStateStore , ServiceStack.Redis 配置web.config <sessionState mode ...

  4. jquery 获取和设置 checkbox radio 和 select option的值?

    ============== 获取和设置 checkbox radio 和 select的值? === val()函数, 其名字就表达了 它的意思: 他就是= value 的简写! val就是valu ...

  5. [歪谈]拽一个贵人出来给你"当炮架子"

    我们在古装神话剧中经常会听到某个“先知”对前来算命的人说:你会在某某时刻遇到你的贵人.而这个贵人会在事业上助你一臂之力. 这里有个问题:贵人到底是什么?我们怎样去寻找我们的贵人. 前几天有个网友来咨询 ...

  6. ios如何普安短图片类型

    很多时候需要知道服务器返回的图片是.png还是.jpg或者是.git, 两种方式 1,获取扩展名 //图片    NSString *image = @"4351141241.GIT&quo ...

  7. HDU 2007

    /*杭电ACM ID:2007*/ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { int in1, in2 ...

  8. Android与Dalvik

    自学android的同事说:Android 这个妈蛋!! 当初就应该选择c++/c 来开发.现在为了效率又搞ART.简直是折腾,art在android5.0 的时候就是默认了.前段时间还在学习andr ...

  9. pipe-filter 真难找啊

    http://blog.csdn.net/absurd/article/details/4307903

  10. 2015多校1006.First One

    First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...