洛谷P3149题解分享
原题目
https://www.luogu.com.cn/problem/P3149
代码
#include<bits/stdc++.h>
#define int long long
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int N = 4e5+24;
int tree[N<<2],tag[N<<2];
int a[N],b[N];
//a:二分数组
set<int>q;
int f[N],nxd[N];
inline int rd(int &x){
char c= getchar();
int f= 1;
while(c>'9'||c<'0'){
if(c=='-')
f=-f;
c = getchar();
}
x = 0;
do{
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}while(c<='9'&&c>='0');
x*=f;
return x;
}//基操快读
inline void Push_up(int rt){
tree[rt] = tree[ls]+tree[rs];
return ;
}
void Build(int rt,int l,int r){
if(l==r){
tree[rt] = nxd[l];
return ;
}
int mid = (l+r)>>1;
Build(ls,l,mid);
Build(rs,mid+1,r);
Push_up(rt);
return ;
}
void Modify(int rt,int l,int r,int L,int R,int x){
if(L<=l&&R>=r){
tree[rt]+=x*(r-l+1);
return ;
}
int mid = (l+r)>>1;
if(L<=mid)
Modify(ls,l,mid,L,R,x);
if(R>mid)
Modify(rs,mid+1,r,L,R,x);
Push_up(rt);
return;
}
int Query(int rt,int l,int r,int L,int R){
if(L<=l&&R>=r)
return tree[rt];
int mid =(l+r)>>1;
int ret=0;
if(L<=mid)
ret+=Query(ls,l,mid,L,R);
if(R>mid)
ret+=Query(rs,mid+1,r,L,R);
return ret;
}
inline int Bin(int x,int L,int R){
int l =L,r = R,mid;
do{
mid = (l+r)>>1;
if( a[mid] >= x )
r = mid;
else
l = mid+1;
}while(l<r);
return l;
}//找到排位
signed main(){
int n,m,op,l,r,x,ret,ins;
int opt,key;
rd(m);rd(opt);
for(int i=1;i<=m;i++){
rd(b[i]);
q.insert(b[i]);
}
//输入
n = 0;
for(set<int>::iterator it = q.begin();it!=q.end();it++){
a[++n] = *it;
}
//建树
int ans = 0;
int k = 0;
int rec = 0;
//rec记录不比当前大的正序对
for(int i=1;i<=m;i++){
k = Bin(b[i],1,n);
rec=Query(1,1,n,1,k);//正序对
Modify(1,1,n,k,k,1);
f[k]+=rec;
}
int cnt;
for(int i=1;i<=n;i++){
k = i;
f[k]+=f[k-1];//全部正序对
cnt = Query(1,1,n,1,k);
nxd[k] = (int)cnt*(cnt-1)/2 - f[k];//求得逆序对
}
//狗屎预处理
int up=-1;
cout<<nxd[n]<<endl;
int answer;
while(opt--){
rd(key);
key = b[key];
key = Bin(key,1,n);
up=max(up,key);
answer = nxd[n]-nxd[up];
cout<<answer<<endl;
}
return 0;
}
/*
5 2
1 5 3 4 2
3
4
*/
浙公网安备 33010602011771号