BZOJ - 2141 排队 (动态逆序对,区间线段树套权值线段树)
交换两个数的位置,只有位于两个数之间的部分会受到影响,因此只需要考虑两个数之间有多少数对a[l]和a[r]产生的贡献发生了变化即可。
感觉像是个带修改的二维偏序问题。(修改点$(x,y)$的值,维护和查询位于$(x_1,y_1)$与$(x_2,y_2)$之间的点的个数)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+,inf=0x3f3f3f3f;
int n,m,n2,rt[N<<],ls[N*],rs[N*],sum[N*],tot,a[N],b[N],ans;
#define lson (u<<1)
#define rson (u<<1|1)
#define mid ((l+r)>>1)
void upd2(int p,int x,int& u,int l=,int r=n2) {
if(!u)u=++tot;
sum[u]+=x;
if(l==r)return;
p<=mid?upd2(p,x,ls[u],l,mid):upd2(p,x,rs[u],mid+,r);
}
int qry2(int L,int R,int& u,int l=,int r=n2) {
if(l>=L&&r<=R)return sum[u];
if(l>R||r<L)return ;
return qry2(L,R,ls[u],l,mid)+qry2(L,R,rs[u],mid+,r);
}
void upd(int p,int x,int dx,int u=,int l=,int r=n) {
upd2(x,dx,rt[u]);
if(l==r)return;
p<=mid?upd(p,x,dx,lson,l,mid):upd(p,x,dx,rson,mid+,r);
}
int qry(int L,int R,int L2,int R2,int u=,int l=,int r=n) {
if(l>=L&&r<=R)return qry2(L2,R2,rt[u]);
if(l>R||r<L)return ;
return qry(L,R,L2,R2,lson,l,mid)+qry(L,R,L2,R2,rson,mid+,r);
}
int main() {
scanf("%d",&n);
for(int i=; i<=n; ++i)scanf("%d",&a[i]);
for(int i=; i<=n; ++i)b[i]=a[i];
sort(b+,b++n),n2=unique(b+,b++n)-(b+);
for(int i=; i<=n; ++i)a[i]=lower_bound(b+,b++n2,a[i])-b;
for(int i=; i<=n; ++i)ans+=qry(,n,a[i]+,n2),upd(i,a[i],);
printf("%d\n",ans);
scanf("%d",&m);
while(m--) {
int l,r;
scanf("%d%d",&l,&r);
if(l>r)swap(l,r);
if(l==r||a[l]==a[r]);
else {
if(a[l]<a[r])ans+=qry(l+,r-,a[l]+,a[r])+qry(l+,r-,a[l],a[r]-)+;
else ans-=qry(l+,r-,a[r]+,a[l])+qry(l+,r-,a[r],a[l]-)+;
upd(l,a[l],-),upd(l,a[r],);
upd(r,a[r],-),upd(r,a[l],);
swap(a[l],a[r]);
}
printf("%d\n",ans);
}
return ;
}
还有理论上能够AC的线段树套treap的版本,可惜常数太大TLE了~QAQ~
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+,inf=0x3f3f3f3f;
int n,m,n2,rt[N<<],ch[N*][],val[N*],siz[N*],rd[N*],tot,a[N],b[N],ans;
#define lson (u<<1)
#define rson (u<<1|1)
#define mid ((l+r)>>1)
void pu(int u) {siz[u]=siz[ch[u][]]+siz[ch[u][]]+;}
int newnode(int x) {int u=++tot; ch[u][]=ch[u][]=,siz[u]=,val[u]=x,rd[u]=rand(); return u;}
void rot(int& u,int f) {
int v=ch[u][f];
ch[u][f]=ch[v][f^],ch[v][f^]=u;
pu(u),pu(v),u=v;
}
void ins(int& u,int x) {
if(!u) {u=newnode(x); return;}
int f=x>val[u];
ins(ch[u][f],x);
if(rd[ch[u][f]]>rd[u])rot(u,f);
if(u)pu(u);
}
void del(int& u,int x) {
if(!u)return;
if(val[u]==x) {
if(!ch[u][]||!ch[u][])u=ch[u][]|ch[u][];
else {
int f=rd[ch[u][]]>rd[ch[u][]];
rot(u,f),del(ch[u][f^],x);
}
} else del(ch[u][x>val[u]],x);
if(u)pu(u);
}
int lb(int u,int x) {
int ret=;
for(; u; u=ch[u][x>val[u]])if(val[u]>=x)ret=val[u];
return ret;
}
int ub(int u,int x) {
int ret=;
for(; u; u=ch[u][x>=val[u]])if(val[u]>x)ret=val[u];
return ret;
}
int rnk(int u,int x) {
int ret=;
for(; u; u=ch[u][x>val[u]])if(x>val[u])ret+=siz[ch[u][]]+;
return ret+;
}
int sum(int u,int l,int r) {return l>r?:rnk(u,ub(u,r))-rnk(u,lb(u,l));}
void upd(int p,int x,int dx,int u=,int l=,int r=n) {
dx==?ins(rt[u],x):del(rt[u],x);
if(l==r)return;
p<=mid?upd(p,x,dx,lson,l,mid):upd(p,x,dx,rson,mid+,r);
}
int qry(int L,int R,int L2,int R2,int u=,int l=,int r=n) {
if(l>=L&&r<=R)return sum(rt[u],L2,R2);
if(l>R||r<L)return ;
return qry(L,R,L2,R2,lson,l,mid)+qry(L,R,L2,R2,rson,mid+,r);
}
void build(int u=,int l=,int r=n) {
ins(rt[u],~inf),ins(rt[u],inf);
if(l==r)return;
build(lson,l,mid),build(rson,mid+,r);
}
int main() {
srand(time());
scanf("%d",&n);
for(int i=; i<=n; ++i)scanf("%d",&a[i]);
for(int i=; i<=n; ++i)b[i]=a[i];
sort(b+,b++n),n2=unique(b+,b++n)-(b+);
for(int i=; i<=n; ++i)a[i]=lower_bound(b+,b++n2,a[i])-b;
build();
for(int i=; i<=n; ++i)ans+=qry(,n,a[i]+,n2),upd(i,a[i],);
printf("%d\n",ans);
scanf("%d",&m);
while(m--) {
int l,r;
scanf("%d%d",&l,&r);
if(l>r)swap(l,r);
if(l==r||a[l]==a[r]);
else {
if(a[l]<a[r])ans+=qry(l+,r-,a[l]+,a[r])+qry(l+,r-,a[l],a[r]-)+;
else ans-=qry(l+,r-,a[r]+,a[l])+qry(l+,r-,a[r],a[l]-)+;
upd(l,a[l],-),upd(l,a[r],);
upd(r,a[r],-),upd(r,a[l],);
swap(a[l],a[r]);
}
printf("%d\n",ans);
}
return ;
}
后续:我把treap的区间求和方式改了稍微改了一下,卡时过掉了~~
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+,inf=0x3f3f3f3f;
int n,m,n2,rt[N<<],ch[N*][],val[N*],siz[N*],rd[N*],tot,a[N],b[N],ans;
#define lson (u<<1)
#define rson (u<<1|1)
#define mid ((l+r)>>1)
void pu(int u) {siz[u]=siz[ch[u][]]+siz[ch[u][]]+;}
int newnode(int x) {int u=++tot; ch[u][]=ch[u][]=,siz[u]=,val[u]=x,rd[u]=rand(); return u;}
void rot(int& u,int f) {
int v=ch[u][f];
ch[u][f]=ch[v][f^],ch[v][f^]=u;
pu(u),pu(v),u=v;
}
void ins(int& u,int x) {
if(!u) {u=newnode(x); return;}
int f=x>val[u];
ins(ch[u][f],x);
if(rd[ch[u][f]]>rd[u])rot(u,f);
if(u)pu(u);
}
void del(int& u,int x) {
if(!u)return;
if(val[u]==x) {
if(!ch[u][]||!ch[u][])u=ch[u][]|ch[u][];
else {
int f=rd[ch[u][]]>rd[ch[u][]];
rot(u,f),del(ch[u][f^],x);
}
} else del(ch[u][x>val[u]],x);
if(u)pu(u);
}
int lb(int u,int x) {
int ret=;
for(; u; u=ch[u][x>val[u]])if(x>val[u])ret+=siz[ch[u][]]+;
return ret;
}
int ub(int u,int x) {
int ret=;
for(; u; u=ch[u][x>=val[u]])if(x>=val[u])ret+=siz[ch[u][]]+;
return ret;
}
int sum(int u,int l,int r) {return ub(u,r)-lb(u,l);}
void upd(int p,int x,int dx,int u=,int l=,int r=n) {
dx==?ins(rt[u],x):del(rt[u],x);
if(l==r)return;
p<=mid?upd(p,x,dx,lson,l,mid):upd(p,x,dx,rson,mid+,r);
}
int qry(int L,int R,int L2,int R2,int u=,int l=,int r=n) {
if(l>=L&&r<=R)return sum(rt[u],L2,R2);
if(l>R||r<L)return ;
return qry(L,R,L2,R2,lson,l,mid)+qry(L,R,L2,R2,rson,mid+,r);
}
int main() {
srand(time());
scanf("%d",&n);
for(int i=; i<=n; ++i)scanf("%d",&a[i]);
for(int i=; i<=n; ++i)b[i]=a[i];
sort(b+,b++n),n2=unique(b+,b++n)-(b+);
for(int i=; i<=n; ++i)a[i]=lower_bound(b+,b++n2,a[i])-b;
for(int i=; i<=n; ++i)ans+=qry(,n,a[i]+,n2),upd(i,a[i],);
printf("%d\n",ans);
scanf("%d",&m);
while(m--) {
int l,r;
scanf("%d%d",&l,&r);
if(l>r)swap(l,r);
if(l==r||a[l]==a[r]);
else {
if(a[l]<a[r])ans+=qry(l+,r-,a[l]+,a[r])+qry(l+,r-,a[l],a[r]-)+;
else ans-=qry(l+,r-,a[r]+,a[l])+qry(l+,r-,a[r],a[l]-)+;
upd(l,a[l],-),upd(l,a[r],);
upd(r,a[r],-),upd(r,a[l],);
swap(a[l],a[r]);
}
printf("%d\n",ans);
}
return ;
}
BZOJ - 2141 排队 (动态逆序对,区间线段树套权值线段树)的更多相关文章
- 【bzoj3065】带插入区间K小值 替罪羊树套权值线段树
题目描述 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它的随从伏特提出 ...
- Bzoj 2141: 排队 分块,逆序对,树状数组
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1310 Solved: 517[Submit][Status][Discuss] D ...
- [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)
[BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- luogu3380/bzoj3196 二逼平衡树 (树状数组套权值线段树)
带修改区间K大值 这题有很多做法,我的做法是树状数组套权值线段树,修改查询的时候都是按着树状数组的规则找出那log(n)个线段树根,然后一起往下做 时空都是$O(nlog^2n)$的(如果离散化了的话 ...
- CF1093E Intersection of Permutations 树状数组套权值线段树
\(\color{#0066ff}{ 题目描述 }\) 给定整数 \(n\) 和两个 \(1,\dots,n\) 的排列 \(a,b\). \(m\) 个操作,操作有两种: \(1\ l_a\ r_a ...
- Dynamic Rankings(树状数组套权值线段树)
Dynamic Rankings(树状数组套权值线段树) 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[ ...
- 主席树 【权值线段树】 && 例题K-th Number POJ - 2104
一.主席树与权值线段树区别 主席树是由许多权值线段树构成,单独的权值线段树只能解决寻找整个区间第k大/小值问题(什么叫整个区间,比如你对区间[1,8]建立一颗对应权值线段树,那么你不能询问区间[2,5 ...
- BZOJ_3685_普通van Emde Boas树_权值线段树
BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x 若x不存在,插入x 2 x 若x存在,删除x 3 输出当前最小值,若不存 ...
随机推荐
- 移植madplay到jz2440【学习笔记】
平台:jz2440 作者:庄泽彬(欢迎转载,请注明作者) 说明:韦东山一期视频学习笔记 交叉编译工具:arm-linux-gcc (GCC) 3.4.5 PC环境:ubuntu16.04 一.移植ma ...
- 使用C语言扩展Python提供性能
python底层是用c写的,c本身是一个非常底层的语言,所以它做某些事情的效率肯定会比上层语言高一些. 比如有些自动化测试用的python库,会对系统的UI进行一些捕获,点击之类的操作,这必然要用到c ...
- java中泛型的一个小问题
最近做项目,由于java语法不是非常的熟悉,编写代码过程中不难遇到一些问题: 代码里写了一条这种语句: Map<String, List<String>> configFile ...
- PHP学习之路(一)
先前对PHP的学习研究,今总结写下心得!!
- Spring -- spring 中使用jdbc, c3p0连接池, dao概念
1. 示例代码 CustomerDao.java ,dao接口 public interface CustomerDao { public void insertCustomer(Customer ...
- qtjambi_ZC
loadJambiJniLibrary --> loadLibrary --> loadNativeLibrary --> loadLibrary_helper class QApp ...
- mysql学习笔记(window下简单使用+Navict)
之前安装过mysql.最近刚好要重新翻出来看看 发现又忘记了那些命令.还是要百度.所以不如自己整理下 尽管网上有很多相关的介绍.当时想对的不如自己整理出来的舒服 首先是下载安装.网上有很多就不一一罗列 ...
- MySQL连接中出现大量的 init 状态问题
最怕的就是睡一觉醒来,系统出了问题. 大早系统无法登陆,以前没有经验的同学code的代码,竟然 try catch 没有记录异常日志信息. 查的问题一点头绪都没有,一直锁定在公司公共网关接口出了问题. ...
- Microsoft Edge Certified with EBS 12.1 and 12.2
I am very pleased to announce that Microsoft Edge is certified as a new browser for Oracle E-Busines ...
- DCGAN、WGAN、WGAN-GP、LSGAN、BEGAN原理总结及对比
DCGAN.WGAN.WGAN-GP.LSGAN.BEGAN原理总结及对比 from:https://blog.csdn.net/qq_25737169/article/details/7885778 ...