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. PHP第一天

     2017年7月10日是在汉企第一天接触PHP课程,感觉公司很正规,有各种管理和考核制度,管理比较严格.下午看了他们做的第一阶段的项目,感觉挺有意思的,个人感觉PHP不仅要学会,还要熟练作用,需要多加 ...

  2. Day-3: Python基础

    数据类型和变量 Python中直接处理的数据类型主要有以下几种: 整数:Python可以直接处理任意大小的整数,无论正负,都可以直接输入处理: 浮点数:浮点数也叫做小数.有普通写法,如:1.1,也有描 ...

  3. UI设计基础知识和JavaScript

    [PS基础案例] 人物修图.调整画布大小,建立3个图层,并列放到画布中,用修补工具修掉中间的人物,再用橡皮章盖掉边缘的人物,然后扣出人物,放上新的蓝天,用橡皮擦调整透明度,擦掉水天交接的地方,然后调整 ...

  4. 裸机LCD驱动配置

    横屏4.3寸LCD为480*272(行:480个像素点        列:272个行) 1.1  LCD原理图 : Pin1:Von  电源正(这里由硬件自动控制) Pin2:VM/VDEN 数据使能 ...

  5. Swiper 滑动

    1.http://www.swiper.com.cn/download/  下载Swiper.JS  Swiper.CSS 2.引入项目,添加html <div class="cont ...

  6. 为什么说汽车VIN码是汽车唯一的"身份证"

    人有身份证,那么车有吗?当然了,汽车也是有"身份证"的,出厂时就会跟着车辆一起出生, 一般在车辆的挡风玻璃处.按照国际SAE国际规定,Vin码由17位字符组成,其中包含了车辆的生产 ...

  7. 配置VNC SERVER 远程访问

    1.安装软件包 # yum install tigervnc-server -y 2. 配置VNC用户 # vim /etc/sysconfig/vncservers VNCSERVERS=" ...

  8. 201521123084 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 1)线程:指进程中的一个执行流程: 2)一个进程可以同时运行多个不同线程,不同线程执行不同的任务: 3)创建 ...

  9. 201521123060 《Java程序设计》第7周学习总结

    1. 本周学习总结 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 答:contains方法调用indexOf方法,遍历遍历内部用于保存数据的e ...

  10. 201521123013 《Java程序设计》第5周学习总结

    1. 本章学习总结 1.1 尝试使用思维导图总结有关多态和接口的知识点. 1.2可选 使用常规方法总结其他上课内容. 接口:不是类,不能使用new实例化,可用instanceof判断是否实现某接口.接 ...