[BZOJ3295] [Cqoi2011] dynamic reverse order (cdq partition)

https://www.lydsy.com/JudgeOnline/problem.php?id=3295

Ideas:

The first: We can transform in order to delete the insertion order is to first delete the last inserted and then seek to reverse it

The second: we consider the contribution of each point to be deleted sequences 

Delete the current set of x elements, then 1 -x than it should be a big minus  in ( x + 1 ) - N in less than he should be subtracted

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 200005;
int n,m,cnt;
int a[maxn],pos[maxn],tree[maxn];
ll ans[maxn];
struct node{
    int t,x,val,type,id;
    bool friend operator<(const node u,const node v){
        if(u.x==v.x) return u.val<v.val;
        return u.x<v.x;
    }
}q[maxn],p[maxn];
int lowbit(int x){
    return x&(-x);
}
void add(int x,int val){
    while(x<=n){
        tree[x]+=val;
        x+=lowbit(x);
    }
}
int get_sum(int x){
    int res=0;
    while(x){
        res+=tree[x];
        x-=lowbit(x);
    }
    return res;
}
void cdq(int l,int r){
    if(l==r) return ;
    int m=(l+r)>>1;
    for(int i=l;i<=r;i++){
        if(q[i].t<=m) add(q[i].val,q[i].type);
        else 
            ans[q[i].id]+=q[i].type*(get_sum(n)-get_sum(q[i].val));
    }
    for(int i=l;i<=r;i++){
        if(q[i].t<=m) add(q[i].val,-q[i].type);
    }
    for(int i=r;i>=l;i--){
        if(q[i].t<=m) add(q[i].val,q[i].type);
        else ans[q[i].id]+=q[i].type*get_sum(q[i].val-1);
    }
    for(int i=l;i<=r;i++){
        if(q[i].t<=m) add(q[i].val,-q[i].type);
    }
    int q1=l;
    int q2=m+1;
    for(int i=l;i<=r;i++){
        if(q[i].t<=m) p[q1++]=q[i];
        else p[q2++]=q[i];
    }
    for(int i=l;i<=r;i++)
        q[i]=p[i];
    cdq(l,m);
    cdq(m+1,r);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        pos[a[i]]=i;
        q[++cnt]=node({cnt,i,a[i],1,0});
    }
    for(int i=1;i<=m;i++){
        int x;
        scanf("%d",&x);
        q[++cnt]=node({cnt,pos[x],x,-1,i});
    }
    sort(q+1,q+1+cnt);
    cdq(1,cnt);
    for(int i=1;i<=m;i++){
        printf("%lld\n",ans[i-1]);
        ans[i]+=ans[i-1];
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/MengX/p/11503124.html