bzoj3295: [Cqoi2011]动态逆序对
Posted sssy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3295: [Cqoi2011]动态逆序对相关的知识,希望对你有一定的参考价值。
题目链接
题解
好神呐,删除转化为插入,然后得到了插入的时间关系
然后问题就转化成了三维偏序问题
代码
#include <iostream>
#include <cstdio>
// n * (2 * n + 1) + 1;
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=2e5+5;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n,m;
int pos[N];
struct Q{
int t,x,y;
Q(int t,int id,int v):t(t),x(id),y(v){}
bool operator < (const Q & A)const{
return x == A.x ? y < A.y : x < A.x;
}
}q[N],t[N];
inline bool cmp(const Q &q,const Q &b) {
return q.t == b.t ? q.x<b.x : q.t<b.t;
}
int c[N];
namespace BIT {
#define lowbit(x) (x & -x)
int sum[maxn];
void add(int idx,int val) {
for(;idx <= n;idx += lowbit(idx)) sum[idx] += val;
}
int query(int idx) {
int ret = 0;for(;idx;idx -= lowbit(idx)) ret += sum[idx];
return ret;
}
}
LL ans[N];
void cdq(int l,int r) {
if(l == r) return;
int mid = (l + r) >> 1;
cdq(l,mid); cdq(mid + 1,r);
int i = l,j = mid + 1,p = l;
while(i <= mid && j <= r) {
if(q[i] < q[j]) BIT::add(q[i].y,1),t[p ++] = q[i ++];
else ans[q[j].t] += BIT::query(n) - (q[j].y) , t[p++] = q[j ++];
}
for(int i = l;i <= mid;i ++) add(q[i].y,- 1);
for(int i = l;i <= r;i ++) q[i] = t[i];
for(int i = r;i >= l;i --) {
if(q[i].t <= mid) add(q[i].y,1);
else ans[q[i].t] += sum(q[i].y);
}
for(int i=l;i<=r;i++) if(q[i].t<=mid) add(q[i].y,-1);
}
int main() {
n = read(); m = read();
for(int i = 1;i <= n ;i ++) q[i] = Q(0,i,read()) , pos[q[i].y] = i;
int Tim = n;
for(int i = 1;i <= m;i ++) q[pos[read()]].t = Tim --;
for(int i = 1;i <= n;i ++) if(!q[i].t) q[i].t = Tim --;
sort(q + 1,q + 1 + n,cmp);
cdq(1,n);
for(int i=1;i<=n;i++) ans[i]+=ans[i-1];
for(int i=n;i>=n-m+1;i--) printf("%lld
",ans[i]);
}
以上是关于bzoj3295: [Cqoi2011]动态逆序对的主要内容,如果未能解决你的问题,请参考以下文章