bzoj3295: [Cqoi2011]动态逆序对

题目链接

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\n",ans[i]);
} 

猜你喜欢

转载自www.cnblogs.com/sssy/p/9260532.html