码迷,mamicode.com
首页 > 其他好文 > 详细

P1975 [国家集训队]排队

时间:2019-01-19 21:09:10      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:ace   lse   add   inline   处理   交换   problem   unique   不重复   

题目

P1975 [国家集训队]排队

做法

逆序对的题当然想办法用cdq做

交换数列的位置好像不好处理,加个时间轴,把交换操作换成:删、删、加、加(位置可变换)

删的贡献系数为\((-1)\),加的贡献系数为\((1)\),然后丢到树状数组也是根据这个系数,这样可以保证不重复统计同一位置

位置为第一维,时间为第二维,注意排序位置时:\(x_1==x_2\)&&\(y_1<y_2\),因为\(y_1\)放到后面会影响\(x_2\)

My complete code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
using namespace std;
typedef long long LL;
const LL maxn=1e5;
inline LL Read(){
    LL x(0),f(1);char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;c=getchar();
    }
    while(c>='0'&&c<='9')
        x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}
struct node{
    LL t,x,y,w,id;
    bool operator <(const node &b)const{
        return (x<b.x||(x==b.x&&y<b.y));
    }
}a[maxn],Kl[maxn];
LL n,m,tot,cnt,num,tim;
LL tmp[maxn],val[maxn],tree[maxn],ans[maxn];
inline LL Lowbit(LL x){
    return x&(-x);
}
inline LL Query(LL x){
    LL ret(0);
    for(;x;x-=Lowbit(x))
        ret+=tree[x];
    return ret;
}
inline void Add(LL x,LL c){
    for(;x<=tot;x+=Lowbit(x))
        tree[x]+=c;
}
void Cdq(LL l,LL r){
    if(l==r)
        return;
    LL mid(l+r>>1);
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Add(a[i].y,a[i].w);
        else
            ans[a[i].id]+=a[i].w*(Query(tot)-Query(a[i].y));
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Add(a[i].y,-a[i].w);
    
    for(LL i=r;i>=l;--i)
        if(a[i].t<=mid)
            Add(a[i].y,a[i].w);
        else
            ans[a[i].id]+=a[i].w*(Query(a[i].y-1));
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Add(a[i].y,-a[i].w);
    
    LL t1(l-1),t2(mid);
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Kl[++t1]=a[i];
        else
            Kl[++t2]=a[i];
    for(LL i=l;i<=r;++i)
        a[i]=Kl[i];
    Cdq(l,mid),Cdq(mid+1,r);
}
int main(){
    n=Read();
    for(LL i=1;i<=n;++i)
        tmp[i]=val[i]=Read();
    sort(tmp+1,tmp+1+n); tot=unique(tmp+1,tmp+1+n)-tmp-1;
    for(LL i=1;i<=n;++i)
        val[i]=lower_bound(tmp+1,tmp+1+tot,val[i])-tmp;
    for(LL i=1;i<=n;++i)
        a[++num]=(node){++tim,i,val[i],1,0};
    m=Read();
    for(LL i=1;i<=m;++i){
        LL x(Read()),y(Read());
        a[++num]=(node){++tim,y,val[x],1,i},
        a[++num]=(node){++tim,x,val[y],1,i},
        a[++num]=(node){++tim,x,val[x],-1,i},
        a[++num]=(node){++tim,y,val[y],-1,i};
        swap(val[x],val[y]);
    }
    sort(a+1,a+1+num);
    Cdq(1,num);
    printf("%lld\n",ans[0]);
    for(LL i=1;i<=m;++i){
        ans[i]+=ans[i-1],
        printf("%lld\n",ans[i]);
    }
    return 0;
}/*
3
130 150 140
2
2 3
1 3
*/

P1975 [国家集训队]排队

标签:ace   lse   add   inline   处理   交换   problem   unique   不重复   

原文地址:https://www.cnblogs.com/y2823774827y/p/10293103.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!