【题目链接】:http://codeforces.com/problemset/problem/785/E

【题意】



给你一个初始序列1..n顺序

然后每次让你交换任意两个位置上面的数字;

让你实时输出q个操作,每个操作过后整个序列逆序对的个数;

【题解】



分块法;

分成根号n个块.

每个块按照数字升序排;

然后再用一个a数组具体记录每个位置上的数字;

找逆序对的方式如下:

对于交换l,r

查找l+1..r-1当中比a[l]小的数字,比a[l]大的数字;

查找l+1..r-1当中比a[r]小…比..大的数字;

根据这4个参数来更新逆序对的个数;

这就要求查询l+1..r-1当中比x小的数的个数;

对于belong[l]块,->belong[i]指的是第i个位置上面的数字对应的是第几个块

在l..R[belong[l]]当中找比x小的数->暴力枚举就好

在L[belong[r]]..r当中找比x小的数->也是暴力枚举;

然后在belong[l]+1..belong[r]-1这些块中,用二分(lower_bound)查找比x小的数的个数(因为是有序的,所以可以这样做);

然后如果a[l]< a[r]则再多递增一个逆序对否则减少1个

然后交换这两个数;

->有序的vector中交换,然后原数组a[i]中也要交换;

vector中的交换也可以用lower_bound实现;



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define ps push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%lld",&x)
#define ref(x) scanf("%lf",&x) typedef pair<int, int> pii;
typedef pair<LL, LL> pll; const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
const double pi = acos(-1.0);
const int K = 500+20;//500个块
const int N = 2e5 + 100; int n,q,belong[N],l[K],r[K],a[N];
LL ans = 0;
vector <int> v[K]; void init()
{
int len = sqrt(n);
if ((len*len) != n)
{
len++;
}
rep1(i, 1, n)
{
belong[i] = ((i - 1) / len) + 1;
v[belong[i]].ps(i);
a[i] = i;
}
rep1(i, 1, len)
{
l[i] = len*(i - 1) + 1;
r[i] = len*i;
}
if ((len*len) != n)
r[len] = n;
} LL smaller(int L, int R, LL x)
{
if (L > R) return 0;
LL cnt = 0;
if (belong[L] == belong[R])
{
rep1(i, L, R)
{
if (a[i] < x)
cnt++;
}
return cnt;
} rep1(i, L, r[belong[L]])
{
if (a[i] < x)
cnt++;
} rep1(i, belong[L] + 1, belong[R] - 1)
{
LL pos = lower_bound(v[i].begin(), v[i].end(), x) - v[i].begin()+1;
cnt += pos;
} rep1(i, l[belong[R]], R)
if (a[i] < x)
cnt++;
return cnt;
} void change(int l, int r)
{
int x = belong[l],y = belong[r];
v[x].erase(lower_bound(v[x].begin(), v[x].end(), a[l]));
v[x].insert(upper_bound(v[x].begin(), v[x].end(), a[r]),a[r]); v[y].erase(lower_bound(v[y].begin(), v[y].end(), a[r]));
v[y].insert(upper_bound(v[y].begin(), v[y].end(), a[l]), a[l]);
swap(a[l], a[r]);
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
rei(n), rei(q);
init();
rep1(i, 1, q)
{
int l, r;
rei(l), rei(r);
if (l > r) swap(l, r);
if (l == r)
{
printf("%lld\n", ans);
continue;
}
LL temp = smaller(l + 1, r - 1, a[l]);
LL temp1 = r - 1 - (l + 1) + 1 - temp;
//temp个数比a[l]小 temp1个数比a[l]大
//之后a[l]会跑到r位置
ans -= temp; ans += temp1;
temp = smaller(l + 1, r - 1, a[r]);
temp1 = r - 1 - (l + 1) + 1 - temp;
//temp个数比a[r]小 temp1个数比a[r]大
//之后a[r]会跑到l位置
ans += temp; ans -= temp1;
if (a[l] < a[r])
ans++;
else
ans--;
change(l, r);
printf("%lld\n", ans);
}
//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}

【codeforces 785E】Anton and Permutation的更多相关文章

  1. 【25.00%】【codeforces 584E】Anton and Ira

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  2. 【27.91%】【codeforces 734E】Anton and Tree

    time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. 【29.89%】【codeforces 734D】Anton and Chess

    time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. 【13.77%】【codeforces 734C】Anton and Making Potions

    time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. 【81.37%】【codeforces 734B】Anton and Digits

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  6. 【77.39%】【codeforces 734A】Anton and Danik

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. 【codeforces 508B】Anton and currency you all know

    [题目链接]:http://codeforces.com/contest/508/problem/B [题意] 给你一个奇数; 让你交换一次数字; 使得这个数字变成偶数; 要求偶数要最大; [题解] ...

  8. 【codeforces 785D】Anton and School - 2

    [题目链接]:http://codeforces.com/contest/785/problem/D [题意] 给你一个长度为n的括号序列; 让你删掉若干个括号之后,整个序列变成前x个括号为左括号,后 ...

  9. 【codeforces 734F】Anton and School

    [题目链接]:http://codeforces.com/problemset/problem/734/F [题意] 给你两个数组b和c; 然后让你找出一个非负数组a满足题中所给关系; [题解] 有个 ...

随机推荐

  1. VS2010中使用AnkhSvn

    VS2010中使用AnkhSvn   今天想到要在自己的开发环境IDE(Visual Studio 2010)中安装一个代码管理器的插件,本人在使用VS2005的时候一直都是使用AnkhSvn-2.1 ...

  2. 第一周 Leetcode 57. Insert Interval (HARD)

    Insert interval  题意简述:给定若干个数轴上的闭区间,保证互不重合且有序,要求插入一个新的区间,并返回新的区间集合,保证有序且互不重合. 只想到了一个线性的解法,所有区间端点,只要被其 ...

  3. [Swift通天遁地]三、手势与图表-(10)创建包含圆点、方形、三角形图标的散点图表

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. HDU 5306 吉司机线段树

    思路: 后面nlogn的部分是伪证... 大家可以构造数据证明是这是nlog^2n的啊~ 吉老司机翻车了 //By SiriusRen #include <cstdio> #include ...

  5. Spring Cloud (9) 服务容错保护-Hystrix断路器

    断路器 断路器本身是一种开关装置,用于在电路上保护线路过载,当线路中又电路发生短路时,断路器能够及时的切断故障电路,放置发生过载.发热.甚至起火等严重后果. 在分布式架构中,断路器模式的作用也是类似, ...

  6. 【年终糖果计划】跟风领一波糖果 candy.one 领取教程

    糖果领取网址(较为稳定):https://candy.one/i/1474564 用微信和QQ打开的朋友请复制到其他浏览器打开 糖果领取网址(较为稳定):https://candy.one/i/147 ...

  7. SQl基本操作——视图

    视图适合频繁查询的表:将一个查询结果作为虚拟表提供给开发人员.安全性高,视图只能查询不能修改,它是一张虚拟表.查询方便,逻辑清晰,但是性能低,一般情况下不如自己写sql语句. --创建视图 creat ...

  8. Oracle Sequence不设置cache参数的几个潜在问题(转载)

    转载于 http://www.uml.org.cn/sjjm/201204065.asp 在Oracle中,我们没有MYSQL和SQL                           Server ...

  9. PHP 之用证书对数据进行签名、验签、加密、解密

    /** * 对数据进行签名 * $data = 'If you are still new to things, we’ve provided a few walkthroughs to get yo ...

  10. $.extend 合并对象(处理可传入0个或多个参数)

    function test(options){             $.extend({ },this.Default,options);                  var v = thi ...