思路

序列中

i 1 2 3 4 5 6 7 8 9 10
a[i] a b c L d e f R g h

现逆序对为ans,要交换L,R

则\([1,3],[9,10]\)这两段区间的都不会被他俩影响 (因为L,R和他们相对位置没变啦)

所以现在我们只需要考虑区间\([4,8]\)就好,其他的不考虑在内

一个数对一个区间产生逆序对的贡献为

① 前面大于他的数的个数 (在区间前面)

② 后面小于他的数的个数 (在区间后面)

因为\(L,R\)之间的区间3,6是不变的(废话)

\(L,R\)又在区间两端

那么很显然的

\(ans=ans-(L对区间zz的贡献②)+(L对区间zz的贡献①)-(R对区间zz的贡献①)+(R对区间zz的贡献②)\)

那区间内的贡献咋求啊?

定义不是很明确了吗 就是区间大于x或者小于的个数

\(=>ans-(区间zz内小于L的个数)+(区间zz内大于L的个数)-(区间zz内大于R的个数)+(区间zz内小于R的个数)\)(注意,相等的没有任何贡献)

无脑数据结构呗

随便来个带修主席树 (树状数组套线段树)

复杂度\(nlog^{2}n\)

但常数巨大,更新一次ans要询问8次

错误

都是些zz错误

n写成len

特盘忘记输出ans

代码

//天苍苍,野茫茫,代码怎么这么长
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=1e5+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,ans,len,rt[maxn],a[maxn],lsh[maxn],cnt;
int thu[maxn];
struct node {
int ch[2],siz;
}e[maxn*30];
void build(int &now,int old,int l,int r,int k) {
now=++cnt;
e[now]=e[old];
e[now].siz++;
if(l==r) return;
int mid=(l+r)>>1;
if(k<=mid) build(e[now].ch[0],e[old].ch[0],l,mid,k);
else build(e[now].ch[1],e[old].ch[1],mid+1,r,k);
}
void modify(int &now,int l,int r,int k,int gs) {
if(!now) now=++cnt;
e[now].siz+=gs;
if(l==r) return;
int mid=(l+r)>>1;
if(k<=mid) modify(e[now].ch[0],l,mid,k,gs);
else modify(e[now].ch[1],mid+1,r,k,gs);
}
int query1(int now,int l,int r,int k) { //小于mid的数
if(l>=k) return 0;
if(r<k) {
int tot=e[now].siz;
FOR(i,1,thu[0]) tot+=e[thu[i]].siz;
return tot;
}
int mid=(l+r)>>1;
if(k<=mid) {
FOR(i,1,thu[0]) thu[i]=e[thu[i]].ch[0];
return query1(e[now].ch[0],l,mid,k);
} else {
int tot=e[e[now].ch[0]].siz;
FOR(i,1,thu[0]) tot+=e[e[thu[i]].ch[0]].siz;
FOR(i,1,thu[0]) thu[i]=e[thu[i]].ch[1];
return tot+query1(e[now].ch[1],mid+1,r,k);
}
}
int query2(int now,int l,int r,int k) { //大于mid的数
if(r<=k) return 0;
if(l>k) {
int tot=e[now].siz;
FOR(i,1,thu[0]) tot+=e[thu[i]].siz;
return tot;
}
int mid=(l+r)>>1;
if(k<=mid) {
int tot=e[e[now].ch[1]].siz;
FOR(i,1,thu[0]) tot+=e[e[thu[i]].ch[1]].siz;
FOR(i,1,thu[0]) thu[i]=e[thu[i]].ch[0];
return tot+query2(e[now].ch[0],l,mid,k);
} else {
FOR(i,1,thu[0]) thu[i]=e[thu[i]].ch[1];
return query2(e[now].ch[1],mid+1,r,k);
}
}
int solve(int l,int r,int k,int pd) {//区间内小于(或小于)k的个数
int tmp=0; thu[0]=0;
for(int i=r;i>=1;i-=(i&-i)) thu[++thu[0]]=rt[i+n];
tmp+=pd ? query1(rt[r],1,len,k) : query2(rt[r],1,len,k); thu[0]=0;
for(int i=l-1;i>=1;i-=(i&-i)) thu[++thu[0]]=rt[i+n];
tmp-=pd ? query1(rt[l-1],1,len,k) : query2(rt[l-1],1,len,k); return tmp;
}
namespace get_init_ans {
int sum[maxn];
void BIT_modify(int x) {
for(int i=x;i<=n;i+=(i&-i)) sum[i]++;
}
int BIT_query(int x) {
int tot=0;
for(int i=x;i>=1;i-=(i&-i)) tot+=sum[i];
return tot;
}
void get_ans() {
for(int i=1;i<=n;++i) {
BIT_modify(a[i]);
ans+=i-BIT_query(a[i]);
}
}
}
using namespace get_init_ans;
int main() {
//read
n=read();
FOR(i,1,n) a[i]=lsh[i]=read();
//lsh and init
sort(lsh+1,lsh+1+n);
len=unique(lsh+1,lsh+1+n)-lsh-1;
FOR(i,1,n) {
a[i]=lower_bound(lsh+1,lsh+1+len,a[i])-lsh;
build(rt[i],rt[i-1],1,len,a[i]);
}
//get_ans
get_ans();
cout<<ans<<"\n";
//work
m=read();
FOR(i_ak_ioi,1,m) {
int x=read(),y=read(),l,l1=0,l2=0,r,r1=0,r2=0;
if(a[x]==a[y]) {
cout<<ans<<"\n";
continue;
}
if(x>y) swap(x,y);
//query
l=x+1,r=y-1;
if(l<=r) {
l2=solve(l,r,a[x],1);
l1=solve(l,r,a[x],0);
r2=solve(l,r,a[y],1);
r1=solve(l,r,a[y],0);
}
//update
ans=ans-l2+l1-r1+r2+(a[x]<a[y] ? 1 : -1);
cout<<ans<<"\n";
//update
for(int i=x;i<=n;i+=(i&-i)) {
modify(rt[i+n],1,len,a[x],-1);
modify(rt[i+n],1,len,a[y],1);
}
for(int i=y;i<=n;i+=(i&-i)) {
modify(rt[i+n],1,len,a[y],-1);
modify(rt[i+n],1,len,a[x],1);
}
swap(a[x],a[y]);
}
return 0;
}

luogu1975 [国家集训队]排队的更多相关文章

  1. Luogu-1975 [国家集训队]排队

    Luogu-1975 [国家集训队]排队 题面 Luogu-1975 题解 题意:给出一个长度为n的数列以及m个交换两个数的操作,问每次操作后逆序对数量 时间,下标和数的大小三维偏序,,,把交换操作看 ...

  2. 【LG1975】[国家集训队]排队

    [LG1975][国家集训队]排队 题面 洛谷 题解 又是一个偏序问题 显然\(CDQ\) 交换操作不好弄怎么办? 可以看成两次删除两次插入 排序问题要注意一下 代码 #include <ios ...

  3. [国家集训队]排队 [cdq分治]

    题面 洛谷 和动态逆序对那道题没有什么区别 把一个交换换成两个删除和两个插入 #include <cstdio> #include <cstdlib> #include < ...

  4. P1975 [国家集训队]排队

    题目链接 题意分析 我们考虑 交换两个数\([le,ri]\)的贡献 减少的逆序对数\([le,ri]\)中小于\(num[le]\)以及大于\(num[ri]\)的数 增加的\([le,ri]\)中 ...

  5. P1975 [国家集训队]排队 线段树套平衡树维护动态逆序对查询

    $ \color{#0066ff}{ 题目描述 }$ 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍 ...

  6. 洛谷 P1975 [国家集训队]排队 Lebal:块内排序+树状数组

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

  7. [luoguP1975] [国家集训队]排队(分块)

    传送门 直接暴力分块,然后在每一个块内排序. 查询时可以在每一个块内二分. #include <cmath> #include <cstdio> #include <io ...

  8. 「Luogu P1975 [国家集训队]排队」

    题目大意 给出一个序列 \(h\),支持交换其中的两数,求出每一时刻的逆序对个数. 分析 求逆序对是 \(O(N\log_2N)\) 的,有 \(M\) 个操作,如果暴力求的话时间复杂度就是 \(O( ...

  9. BZOJ 2039: [2009国家集训队]employ人员雇佣

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1369  Solved: 667[Submit ...

随机推荐

  1. 去掉idea中竖线

    1.现象如下: 2.解决办法. 3.解决后如下:

  2. RabbitMQ的使用场景

    RabbitMQ的使用场景   1 大数据日志收集消息中间件应用场景     2 消息中间件在搜索系统DIH(伪实时)中的应用       伪实时的搜索系统:   后台系统:(作为生产者发送消息)   ...

  3. 《大话设计模式》c++实现 外观模式

    外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式在什么时候使用呢? 分为三个阶段: (1)首先,在设计初期阶段,应该要有意识的 ...

  4. css解决无论页面长短footer永远置底

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 不能安装vmtools解决:一个命令安装

    https://blog.csdn.net/fly66611/article/details/77994339 换好源 sudo su apt-get update apt-get dist-upgr ...

  6. JVM探秘3---垃圾回收机制详解

    众所周知,Java有自己的垃圾回收机制,它可以有效的释放系统资源,提高系统的运行效率.那么它是怎么运行的呢,这次就来详细解析下Java的垃圾回收 1.什么是垃圾? 垃圾回收回收的自然是垃圾,那么jav ...

  7. Chrome浏览器相关细节整理

    一.上传文件卡死 可能时由于输入法的原因导致上传文件浏览器卡死.将输入法改为英文模式再操作上传文件就不会卡死了.

  8. Linux服务器---流量监控bandwidthd

    Bandwidthd Bandwidthd是一款免费的流量监控软件,它可以用图标的方式展现出网络流量行为,并且可区分出ftp.tcp等各种协议的流量. 1.安装一些依赖软件 [root@localho ...

  9. Fiddler4入门--手机抓包工具安装和使用说明

    Fiddler4入门--手机抓包工具安装和使用说明.电脑最好是笔记本连同一个wifi,这样能和手机保持统一局域网内. 很多区块链dapp项目方风控做的很差,利用fiddler抓包分析找一些漏洞,然后利 ...

  10. Vue2.0,Express实现的简单跨域

    https://www.cnblogs.com/kevin-zjy-blog/p/7357220.html 1. 通过jsonp跨域2. document.domain + iframe跨域3. lo ...