Codeforces 785 E. Anton and Permutation

题目大意:给出n,q。n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询。每次查询给出两个数l,r,要求将索引为l,r的两个数交换位置,并给出交换后数组中的逆序对数。

思路:此题用到了分块的思想,即将这组数分为bsz块,在每一块上建Fenwick树,对于每次查询,只需要处理l,r中间的块和l,r所在块受影响的部分。具体实现见代码及注释。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<cmath>
#include<algorithm>
#include<climits>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef map<int,int> M;
typedef queue<int> Q;
typedef set<int> S;
typedef vector<int> V;
const int maxn=2e5+10,bsz=2000;
int n;
int br[maxn],bl[maxn],b[maxn]; //br[i]为编号为i块的右界,bl[i]为编号为i块的左界,b[i]为i点对应的块编号
struct fenwick
{
int sum[maxn];
void add(int p,int x)
{
while (p<=n)
{
sum[p]+=x;
p+=p&-p;
}
}
int qry(int p)
{
int res=0;
while (p)
{
res+=sum[p];
p-=p&-p;
}
return res;
}
} fen[maxn/bsz+1];
int a[maxn];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int i,j,m,q;
cin>>n>>q;
//分块、定界
int bn=(n-1)/bsz+1;
for (i=0;i<bn;++i)
{
bl[i]=i*bsz;
br[i]=min(n,i*bsz+bsz);
for (j=bl[i];j<br[i];++j)
b[j]=i;
}
//数据初始化,上树
for (i=0;i<n;++i)
{
a[i]=i+1;
fen[b[i]].add(a[i],1);
}
//处理query
ll ans=0;
while (q--)
{
int l,r;
cin>>l>>r;
l--;
r--;
if (l==r)
{
cout<<ans<<endl;
continue;
}
else if (l>r)
swap(l,r);
int less_l=0,less_r=0;
//处理l,r中间的块
for (i=b[l]+1;i<b[r];++i)
{
less_l+=fen[i].qry(a[l]);
less_r+=fen[i].qry(a[r]);
}
//处理l,r所在块的影响部分
if (b[l]!=b[r])
{
for (i=l;i<br[b[l]];++i)
{
less_l+=a[i]<a[l];
less_r+=a[i]<a[r];
}
for (i=bl[b[r]];i<=r;++i)
{
less_l+=a[i]<a[l];
less_r+=a[i]<a[r];
}
}
else
{
for (i=l;i<=r;++i)
{
less_l+=a[i]<a[l];
less_r+=a[i]<a[r];
}
}
//由于计算less_l和less_r时,对于端点l,r的处理有重复计数,因此需要修正答案
if (a[l]<a[r])
ans--;
else
ans++;
//更新Fenwick树
fen[b[l]].add(a[l],-1);
fen[b[r]].add(a[r],-1);
swap(a[l],a[r]);
fen[b[l]].add(a[l],1);
fen[b[r]].add(a[r],1);
//处理答案
int total=r-l;
ll tmpl=(total-less_l)-less_l;//增加的逆序对数-减少的逆序对数
ll tmpr=less_r-(total-less_r); //增加的逆序对数-减少的逆序对数
ans+=tmpl+tmpr;
cout<<ans<<endl;
}
return 0;
}

Codeforces 785 E. Anton and Permutation(分块,树状数组)的更多相关文章

  1. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

  2. 【BZOJ 3295】动态逆序对 - 分块+树状数组

    题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...

  3. 【bzoj2141】排队 分块+树状数组

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

  4. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  5. 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu

    https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...

  6. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  7. Codeforces 703D Mishka and Interesting sum(树状数组+扫描线)

    [题目链接] http://codeforces.com/contest/703/problem/D [题目大意] 给出一个数列以及m个询问,每个询问要求求出[L,R]区间内出现次数为偶数的数的异或和 ...

  8. CF Educational Codeforces Round 10 D. Nested Segments 离散化+树状数组

    题目链接:http://codeforces.com/problemset/problem/652/D 大意:给若干个线段,保证线段端点不重合,问每个线段内部包含了多少个线段. 方法是对所有线段的端点 ...

  9. 【XSY2111】Chef and Churus 分块 树状数组

    题目描述 有一个长度为\(n\)的数组\(A\)和\(n\)个区间\([l_i,r_i]\),有\(q\)次操作: \(1~x~y\):把\(a_x\)改成\(y\) \(2~x~y\):求第\(l\ ...

随机推荐

  1. singleWsdl和wsdl区别,Axis2和CXF对比

    WebService是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互. 其实WebSer ...

  2. 怎样单独遍历NodeList的键、值和键值对

    1. 单独遍历键: NodeList.prototype.keys(); 2. 单独遍历值: NodeList.prototype.values(); 3. 遍历键值对: NodeList.proto ...

  3. Scala学习七——包和引入

    一.本章要点 包也可也可以像内部类那样嵌套 包路径不是绝对路径 包声明链x.y.z并不自动将中间包x和x.y变成可见 位于文件顶部不带花括号的包声明在整个文件范围内有效 包对象可以持有函数和变量 引入 ...

  4. Redis基本数据

    Redis Redis是一个速度非常快的非关系数据库(NoSql),它可以存储键(key)与五种不同的值(value)之间的映射.可以将存储的内存的键值对数据持久化到硬盘. Redis 数据结构 Re ...

  5. 数据库HAVING的使用

    HAVING语句通常与GROUP BY语句联合使用,用来过滤由GROUP BY语句返回的记录集. HAVING语句的存在弥补了WHERE关键字不能与聚合函数联合使用的不足. 记录一下

  6. vue入门:(组件)

    模板:(template)模板声明了数据和最终展现给用户的DOM之间的映射关系. 初始数据:(data)一个组件的初始数据状态.对于可复用的组件来说,通常是私有的状态. 接收外部参数:(props)组 ...

  7. vue入门:(v-for指令与列表渲染)

    v-for渲染列表 维护状态 数组变异方法与替换数组 $set.$remove 对象属性实现列表渲染 一.v-for渲染列表 语法:v-for="item in items" 先来 ...

  8. 测试使用Timer定时调用http接口

    转自:https://blog.csdn.net/qq_36004521/article/details/80101881

  9. MySQL数据库笔记二:数据类型及数据库操作

    三.MySQL数据库数据类型 MySQL数据库中支持多种数据类型:数值型.字符型.日期型 常用的数据类型: 1.整型 int:整形,存储整数 int(M):M表示预期值.与存储大小和数值的范围无关. ...

  10. three.js之性能监视器

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...