题目链接

交换两个数的位置,只有位于两个数之间的部分会受到影响,因此只需要考虑两个数之间有多少数对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 排队 (动态逆序对,区间线段树套权值线段树)的更多相关文章

  1. 【bzoj3065】带插入区间K小值 替罪羊树套权值线段树

    题目描述 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它的随从伏特提出 ...

  2. Bzoj 2141: 排队 分块,逆序对,树状数组

    2141: 排队 Time Limit: 4 Sec  Memory Limit: 259 MBSubmit: 1310  Solved: 517[Submit][Status][Discuss] D ...

  3. [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)

    [BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...

  4. BZOJ2141排队——树状数组套权值线段树(带修改的主席树)

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...

  5. luogu3380/bzoj3196 二逼平衡树 (树状数组套权值线段树)

    带修改区间K大值 这题有很多做法,我的做法是树状数组套权值线段树,修改查询的时候都是按着树状数组的规则找出那log(n)个线段树根,然后一起往下做 时空都是$O(nlog^2n)$的(如果离散化了的话 ...

  6. CF1093E Intersection of Permutations 树状数组套权值线段树

    \(\color{#0066ff}{ 题目描述 }\) 给定整数 \(n\) 和两个 \(1,\dots,n\) 的排列 \(a,b\). \(m\) 个操作,操作有两种: \(1\ l_a\ r_a ...

  7. Dynamic Rankings(树状数组套权值线段树)

    Dynamic Rankings(树状数组套权值线段树) 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[ ...

  8. 主席树 【权值线段树】 && 例题K-th Number POJ - 2104

    一.主席树与权值线段树区别 主席树是由许多权值线段树构成,单独的权值线段树只能解决寻找整个区间第k大/小值问题(什么叫整个区间,比如你对区间[1,8]建立一颗对应权值线段树,那么你不能询问区间[2,5 ...

  9. BZOJ_3685_普通van Emde Boas树_权值线段树

    BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x  若x不存在,插入x 2 x  若x存在,删除x 3    输出当前最小值,若不存 ...

随机推荐

  1. [转]HBase hbck——检察HBase集群的一致性

    Hbase提供了hbck命令来检查各种不一致问题.hbck的名字仿效了HDFS的fsck命令,后者是一个用于检查HDFS中不一致问题的工具.下面这段非常易懂的介绍出自于hbck的源程序. 检查数据在M ...

  2. 本地存储(localStorage、sessionStorage、web Database)

    一.sessionStorage和localStorage sessionStorage和localStorage两种方法都是当用户在inPut文本框中输入内容并点击保存数据按钮时保存数据,点击读取数 ...

  3. sublime text3配置ctrl+鼠标左键进行函数跳转【转】

    本文转载自:https://blog.csdn.net/shangdibaozi/article/details/77503426 点击Preferences->Browse Packages进 ...

  4. 初入spring boot(四 )web项目

    1. 模板引擎 spring boot提供了大量的模板引擎,包括FreeMark.Groovy.Thymeleaf.Velocity等,但spring boot中推荐用Thymeleaf,因为Thym ...

  5. scala学习手记39 - 模式匹配

    在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串. 在scala中也有类似的模式匹配语句,即ma ...

  6. Eclipse_下载地址

    1. http://www.eclipse.org/downloads/ http://www.eclipse.org/downloads/packages/ http://archive.eclip ...

  7. Amazon SES介绍 - SES发送邮件的过程

     Amazon SES,  全称Amazon Simple Email Service,即Amazon简单邮件服务,它是Amazon提供的一款供开发人员或公司企业用来处理邮件相关业务的服务,也就是说, ...

  8. 用HyperMesh(7.0)手工修改网格

    检查网格质量并修改 2D->qulifyindex:其中View/Edit/Optimize工具栏功能常用,尤其是Edit页中的Place Node,可以动态地拖动节点并观察单元质量是否符合要求 ...

  9. 从互信息的角度来理解tf-idf

    先介绍tf idf 在一份给定的文件里,词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率.这个数字是对词数(term count)的归一化,以防止它偏向长的文件.( ...

  10. combo

    什么是combo 上一节中我们有一行代码: <script src="http://g.tbcdn.cn/kissy/k/1.4.8/??seed-min.js,import-styl ...