我们把每一次交换看做两个插入两个删除。然后就是一个三维偏序。时间一维,下标一维,权值一维。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=100010;
struct query{
int t,x,y,k,w;
}q[N],c[N];
int ans[N],n,a[N],m,tr[N],b[N],cnt;
bool cmp(query a,query b){
return a.t<b.t;
}
int lowbit(int x){
return x&-x;
}
void add(int x,int w){
for(int i=x;i<=n;i+=lowbit(i)){
tr[i]+=w;
}
}
int getsum(int x){
int tmp=0;
for(int i=x;i;i-=lowbit(i)){
tmp+=tr[i];
}
return tmp;
}
void cdq1(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
cdq1(l,mid);cdq1(mid+1,r);
int ll=l;int rl=mid+1;int now=0;
while(ll<=mid&&rl<=r){
if(q[ll].x<=q[rl].x){
add(q[ll].y,q[ll].k);
c[++now]=q[ll++];
}
else{
ans[q[rl].w]+=q[rl].k*(getsum(n)-getsum(q[rl].y));
c[++now]=q[rl++];
}
}
while(ll<=mid){
add(q[ll].y,q[ll].k);
c[++now]=q[ll++];
}
while(rl<=r){
ans[q[rl].w]+=q[rl].k*(getsum(n)-getsum(q[rl].y));
c[++now]=q[rl++];
}
for(int i=l;i<=mid;i++){
add(q[i].y,-q[i].k);
}
for(int i=l;i<=r;i++){
q[i]=c[i-l+1];
}
}
void cdq2(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
cdq2(l,mid);cdq2(mid+1,r);
int ll=l;int rl=mid+1;int now=0;
while(ll<=mid&&rl<=r){
if(q[ll].x>=q[rl].x){
add(q[ll].y,q[ll].k);
c[++now]=q[ll++];
}
else{
ans[q[rl].w]+=q[rl].k*getsum(q[rl].y-1);
c[++now]=q[rl++];
}
}
while(ll<=mid){
add(q[ll].y,q[ll].k);
c[++now]=q[ll++];
}
while(rl<=r){
ans[q[rl].w]+=q[rl].k*getsum(q[rl].y-1);
c[++now]=q[rl++];
}
for(int i=l;i<=mid;i++){
add(q[i].y,-q[i].k);
}
for(int i=l;i<=r;i++){
q[i]=c[i-l+1];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
int tot=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++){
a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
q[++cnt].t=cnt;q[cnt].x=i;q[cnt].y=a[i];q[cnt].k=1;q[cnt].w=0;
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
q[++cnt].t=cnt;q[cnt].x=x;q[cnt].y=a[x];q[cnt].k=-1;q[cnt].w=i;
q[++cnt].t=cnt;q[cnt].x=y;q[cnt].y=a[y];q[cnt].k=-1;q[cnt].w=i;
q[++cnt].t=cnt;q[cnt].x=x;q[cnt].y=a[y];q[cnt].k=1;q[cnt].w=i;
q[++cnt].t=cnt;q[cnt].x=y;q[cnt].y=a[x];q[cnt].k=1;q[cnt].w=i;
swap(a[x],a[y]);
}
cdq1(1,cnt);
sort(q+1,q+1+cnt,cmp);
cdq2(1,cnt);
printf("%d\n",ans[0]);
for(int i=1;i<=m;i++){
ans[i]+=ans[i-1];
printf("%d\n",ans[i]);
}
return 0;
}

最新文章

  1. [moka同学笔记]Yii2 数据操作Query Builder 2
  2. sort()排序
  3. Qt学习之路(2)------Qt中的字符串类
  4. Xcode6插件开发
  5. Android Bitmaps缓存
  6. STL之deque(双向队列)
  7. ASP.NET Core的身份认证框架IdentityServer4--(4)添加第三方快捷登录
  8. javascript获取网页地址栏的id
  9. 网络1711-1712班 c 语言评分总表一览
  10. 关于第一次使用vue-cli
  11. 通过type类型 新建对象
  12. sort函数比较cmp写法
  13. Angel - MemoryDataBlock - angel.task.estimize.sample.number
  14. Vue.js 相关知识(动画)
  15. 【SE】Week1 : 四则运算题目生成器批改器程序总结
  16. Python操作Rabbit MQ的5种模式
  17. C#比较时分秒大小,终止分钟默认加十分钟,解决跨天、跨月、跨年的情况
  18. Ubuntu里面vi编辑器在编辑文本时 如何在所有行行首或行尾插入字符
  19. Github - 修改语言统计
  20. javascript 事件相关使用总结01

热门文章

  1. CSS鼠标悬停图片加边框效果,页面布局发生错位的解决办法
  2. 这个夏天有你,有CorelDRAW X7,有理想,有设计!
  3. CorelDRAW X6冰点价加推800套燃爆6月
  4. My97 DatePicker获取自定义日期的前一天
  5. 转:用java调用oracle存储过程总结(比较好理解)
  6. Hadoop2.9.1安装教程_环境Ubuntu_VMware安装
  7. StringUtils 的填充方法
  8. unity 获取UGUI中的Text字的坐标
  9. thinkphp 同一字段不同查询条件实现
  10. jvm 虚拟机的组成部分