Dynamic Inversions

Time Limit: 30000/15000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
SubmitStatus

Problem Description

给出N个数a[1],a[2] ... a[N],有M个操作,每个操作给出x,y两个数,你将a[x],a[y]交换,然后求交换后数组的逆序对个数。
逆序对的意思是1 <= i < j <= N 且a[i] > a[j].

Input

多组数据,每组数据:

一个N,接下来一行有N个数a[1]... a[N]

再下去一行是M,最后M行每行两个数x,y

1 <= N,M <= 10^5, 1 <= x,y <= N,1 <= a[i] <= 50

Output

对于每组数据,输出M + 1行,第一行是开始时的逆序对数目,接下去M行每行一个数,表示这次修改后的逆序对数目

Sample Input

2
1 2
1
2 1
3
1 2 3
3
1 2
2 3
3 1

Sample Output

0
1
0
1
2
1

Hint

第二个样例,一开始1 2 3,逆序对数为0,交换第1,2个元素,变为2 1 3,答案为1,交换第2和3个元素,变为2 3 1,逆序对数为2,交换第3和1个元素,逆序对数为1,此时序列变成1 3  2

二维树状数组做法:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define ll long long
int b[][],a[],n,c[];
int lowbit(int x)
{
return x&(-x);
}
void update1(int x)
{
while(x<)
{
c[x]++;
x+=lowbit(x);
}
}
int query1(int x)
{
int sum=;
while(x>)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update(int x,int y,int z)
{
for(int i=x; i<=; i+=lowbit(i))
for(int j=y; j<=n; j+=lowbit(j))
b[i][j]+=z;
}
int query(int x,int y,int x1,int y1)
{
int ans=,i,j;
for(i=y;i>;i-=lowbit(i))
for(j=y1;j>;j-=lowbit(j))
ans+=b[i][j]; for(i=x-;i>;i-=lowbit(i))
for(j=y1;j>;j-=lowbit(j))
ans-=b[i][j]; for(i=y;i>;i-=lowbit(i))
for(j=x1-;j>;j-=lowbit(j))
ans-=b[i][j]; for(i=x-;i>;i-=lowbit(i))
for(j=x1-;j>;j-=lowbit(j))
ans+=b[i][j];
return ans;
}
int main()
{
int i,m,x,y;
ll ans;
while(~scanf("%d",&n))
{
ans=;
memset(b,,sizeof(b));
memset(c,,sizeof(c));
for(i=; i<=n; i++)
{
scanf("%d",&a[i]);
update1(a[i]);
ans+=i-query1(a[i]);
update(a[i],i,);
}
printf("%lld\n",ans);
scanf("%d",&m);
for(i=; i<m; i++)
{
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
ans-=query(a[y]+,,x+,y);
ans+=query(,a[y]-,x+,y);
ans+=query(a[x]+,,x,y-);
ans-=query(,a[x]-,x,y-);
if(a[x]>a[y])ans--;
else if(a[x]<a[y])ans++;
update(a[x],x,-);
update(a[x],y,);
update(a[y],y,-);
update(a[y],x,);
swap(a[x],a[y]);
printf("%lld\n",ans);
}
}
}

50个一维的做法:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define ll long long
int a[][],b[],n,c[];
int lowbit(int x)
{
return x&(-x);
}
int update(int x)
{
while(x<)
{
b[x]++;
x+=lowbit(x);
}
}
int update1(int i,int x,int y)
{
while(x<=n)
{
a[i][x]+=y;
x+=lowbit(x);
}
}
int query(int x)
{
int sum=;
while(x>)
{
sum+=b[x];
x-=lowbit(x);
}
return sum;
}
int query1(int i,int x)
{
int sum=;
while(x>)
{
sum+=a[i][x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int i,j,m,x,y,z;
ll ans,temp,temp1;
while(~scanf("%d",&n))
{
memset(b,,sizeof(b));
memset(a,,sizeof(a));
memset(c,,sizeof(c));
ans=;
for(i=; i<=n; i++)
{
scanf("%d",&a[][i]);
c[a[][i]]++;
ans+=i-query(a[][i])-;
update(a[][i]);
update1(a[][i],i,);
}
printf("%lld\n",ans);
scanf("%d",&m);
for(i=; i<m; i++)
{
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
z=y-x;
temp=;
for(j=; j<a[][y]; j++)
{
temp+=query1(j,y-)-query1(j,x-);
}
temp1=query1(j,y-)-query1(j,x-);
ans+=temp-(z-temp1-temp);
temp=;
for(j=; j<a[][x]; j++)
{
temp+=query1(j,y-)-query1(j,x-);
}
temp1=query1(j,y-)-query1(j,x-);
ans+=(z-temp1-temp)-temp;
update1(a[][x],x,-);
update1(a[][x],y,);
update1(a[][y],y,-);
update1(a[][y],x,);
swap(a[][y],a[][x]);
printf("%lld\n",ans);
}
}
}

Dynamic Inversions 50个树状数组的更多相关文章

  1. [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  2. HDU 6318 Swaps and Inversions(归并排序 || 树状数组)题解

    题意:一个逆序对罚钱x元,现在给你交换的机会,每交换任意相邻两个数花钱y,问你最少付多少钱 思路:最近在补之前还没过的题,发现了这道多校的题.显然,交换相邻两个数逆序对必然会变化+1或者-1,那我们肯 ...

  3. BZOJ1901: Zju2112 Dynamic Rankings(整体二分 树状数组)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9094  Solved: 3808[Submit][Status][Discuss] Descript ...

  4. BZOJ 1901 Dynamic Rankings (整体二分+树状数组)

    题目大意:略 洛谷传送门 这道题在洛谷上数据比较强 貌似这个题比较常见的写法是树状数组套主席树,动态修改 我写的是整体二分 一开始的序列全都视为插入 对于修改操作,把它拆分成插入和删除两个操作 像$C ...

  5. Swaps and Inversions HDU - 6318 树状数组+离散化

    #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> us ...

  6. Dynamic Rankings ZOJ - 2112(主席树+树状数组)

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  7. ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  8. ZOJ 2112 Dynamic Rankings(树状数组+主席树)

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  9. Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6321  Solved: 2628[Su ...

随机推荐

  1. python基础教程(七)

    本章介绍如何将语句组织成函数,这样,可以告诉计算机如何做事. 下面编写一小段代码计算婓波那契数列(前两个数的和是第三个数)   fibs = [0,1] # 定义一个列表,初始内容是0,1 for i ...

  2. 报表 jasper + ireport5.6

    下载 iReport-5.6.0,jdk7,以及众多lib , 这里我提供下资源(我的百度云) 安装好iReport-5.6.0和jdk7,  在安装目录的\etc\ireport.conf,修改其中 ...

  3. Express + Session 实现登录验证

    1. 写在前面 当我们登录了一个网站,在没有退出登录的情况下,我们关闭了这个网站 ,过一段时间,再次打开这个网站,依然还会是登录状态.这是因为,当我们登录了一个网站,服务器会保存我们的登录状态,直到我 ...

  4. [js高手之路]javascript腾讯面试题学习封装一个简易的异步队列

    这道js的面试题,是这样的,页面上有一个按钮,一个ul,点击按钮的时候,每隔1秒钟向ul的后面追加一个li, 一共追加10个,li的内容从0开始技术( 0, 1, 2, ....9 ),首先我们用闭包 ...

  5. TensorBoard使用

    关于TensorBoard的安装是在安装Tensorflow的过程中就已经默认安装好了,所以安装了Tensorflow就不需要再安装TensorBoard,直接使用就可以了. 具体的使用方法: 命令行 ...

  6. 如何在sublime+chrome中调试php代码?

    1.搭建php本地运行环境具体点击如何使用phpstudy本地搭建多站点(每个站点对应不同的端口) 2.下载php_xdebug.dll, [5.3版以上的php下载地址]http://pecl.ph ...

  7. 《深入浅出MySQL》之数据类型

    MySQL提供了多种数据类型,主要包括数值型.字符串型和日期时间类型.本次博客就来谈谈MySQL中常用的数据类型吧(版本:mysql-5.7.19)! 数值类型 MySQL支持所有标准SQL中数值类型 ...

  8. 软件工程(GZSD2015)第二次作业小结

    第二次作业,从4月7号开始,陆续开始提交作业.根据同学们提交的作业报告,相比第一次作业,已经有了巨大改变,大家开始有了完整的实践,对那些抽象的名词也开始有了直观的感受,这很好.然后有一些普遍存在的问题 ...

  9. 团队作业4——第一次项目冲刺(Alpha版本)6th day

    一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 24点的游戏输入是点击我们给的图片然后会输入相应的数字,之前的所做的出 现了一点问题,在把数字删掉重新输入就不行,这个问题仍然 ...

  10. 201521123061 《Java程序设计》第五周学习总结

    201521123061 <Java程序设计>第五周学习总结 1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 1.代 ...