bzoj 2141 线段树套权值线段树
来源:互联网 发布:猎豹浏览器网络异常 编辑:程序博客网 时间:2024/06/05 19:46
首先交换的两个数两边的数产生的逆序对数不变。
那么只需要考虑中间的数和两个数本身。
只考虑第一个数大于第二个数的情况(小于的情况是这个的逆过程)
首先答案-1(这两个数产生的逆序对)
答案-位置在两个数之间并且值也在两个数之间的数的个数×2
答案-位置在两个数之间并且值与两个数中的一个相等的数的个数
可以用树套树维护这个东西。
#include <bits/stdc++.h>using namespace std;#define N 21000#define M 11000000#define A 1000000010#define ll long longint n,m,cnt,l1,r1,l2,r2;int a[N];int ch[M][2],val[M],root[N<<2];ll ans;struct val_tree{ void insert(int l,int r,int &x,int y,int v) { if(!x)x=++cnt; val[x]+=v; if(l==r)return; int mid=(l+r)>>1; if(mid>=y)insert(l,mid,ch[x][0],y,v); else insert(mid+1,r,ch[x][1],y,v); } int query(int l,int r,int x) { if(l2<=l&&r<=r2) return val[x]; int mid=(l+r)>>1,ret=0; if(mid>=l2)ret+=query(l,mid,ch[x][0]); if(mid<r2) ret+=query(mid+1,r,ch[x][1]); return ret; }}tr2;struct pos_tree{ void insert(int l,int r,int now,int x,int y,int v) { tr2.insert(1,A,root[now],y,v); if(l==r)return; int mid=(l+r)>>1; if(mid>=x)insert(l,mid,now<<1,x,y,v); else insert(mid+1,r,now<<1|1,x,y,v); } int query(int l,int r,int now) { if(l1<=l&&r<=r1) return tr2.query(1,A,root[now]); int mid=(l+r)>>1,ret=0; if(mid>=l1)ret+=query(l,mid,now<<1); if(mid<r1) ret+=query(mid+1,r,now<<1|1); return ret; }}tr1;int main(){ //freopen("tt.in","r",stdin); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); l1=1;r1=n;l2=a[i]+1;r2=A; ans+=tr1.query(1,n,1); tr1.insert(1,n,1,i,a[i],1); } printf("%lld\n",ans); scanf("%d",&m); for(int x,y;m--;) { scanf("%d%d",&x,&y); if(x>y)swap(x,y); if(a[x]==a[y]){printf("%lld\n",ans);continue;} l1=x+1;r1=y-1; if(a[x]>a[y]) { l2=a[y]+1;r2=a[x]-1;ans--; if(r1>=l1&&r2>=l2)ans-=tr1.query(1,n,1)*2; l2=a[y];r2=a[y]; if(r1>=l1)ans-=tr1.query(1,n,1); l2=a[x];r2=a[x]; if(r1>=l1)ans-=tr1.query(1,n,1); } else { l2=a[x]+1;r2=a[y]-1;ans++; if(r1>=l1&&r2>=l2)ans+=tr1.query(1,n,1)*2; l2=a[x];r2=a[x]; if(r1>=l1)ans+=tr1.query(1,n,1); l2=a[y];r2=a[y]; if(r1>=l1)ans+=tr1.query(1,n,1); } tr1.insert(1,n,1,x,a[x],-1); tr1.insert(1,n,1,y,a[y],-1); swap(a[x],a[y]); tr1.insert(1,n,1,x,a[x],1); tr1.insert(1,n,1,y,a[y],1); printf("%lld\n",ans); } return 0;}
0 0
- bzoj 2141 线段树套权值线段树
- bzoj 2120&&2453 线段树套权值线段树
- BZOJ 2141 分块 线段树
- bzoj 线段树专刊
- bzoj 1798 线段树
- BZOJ 1012 线段树
- bzoj 4388 线段树
- BZOJ 1798 线段树
- BZOJ 1112 线段树
- BZOJ 3339 线段树
- bzoj 2957 线段树
- bzoj 1012 线段树
- bzoj 2752 线段树
- bzoj 3519 线段树
- bzoj 1798 线段树
- BZOJ 3038 线段树
- bzoj 3038 线段树
- BZOJ 3110 线段树套线段树
- struts2 action接收文件上传数据处理
- Linux下多个进程或线程同时对一个文件进行写操作
- NoClassDefFoundError
- 注释插件VVDocumenter-Xcode in Xcode8
- 关于settimeout
- bzoj 2141 线段树套权值线段树
- JQuery解析xml的两种方式$.get和$.ajax
- synchronized详解
- 网络安全行业全景图
- li标签的横向排列
- MySQL ERROR 1045 (28000)问题处理
- xtrabackup使用方法简介
- Redis的2种持久化方式Snapshot(RDB)和Append-only file(AOF)的配置和对比
- SQL语句(statement)预处理(preparedStatement)