• P1975 [国家集训队]排队


    题目

    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
    ",ans[0]);
    	for(LL i=1;i<=m;++i){
    		ans[i]+=ans[i-1],
    		printf("%lld
    ",ans[i]);
    	}
    	return 0;
    }/*
    3
    130 150 140
    2
    2 3
    1 3
    */
    
  • 相关阅读:
    ASP.NET中常用的26个优化性能方法(转)
    代码整洁
    【在开发中常用的UI控件】
    【加法计算器--结果label不显示加值】
    【点击textfield的时候不出现键盘】
    【XCODE上的项目运行到模拟器上是一片空白】
    【xcode commit失败 please tell me who you are】
    【storyboard 上没有箭头的解决办法】
    【ios模拟器上没 home键,怎么返回的?】
    【这是一个JAVA开发者的博客~】
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10293103.html
Copyright © 2020-2023  润新知