zoukankan      html  css  js  c++  java
  • 洛谷P3157 [CQOI2011]动态逆序对

    题目大意:

    给定(1)(n)的一个排列,按照给定顺序依次删除(m)个元素,计算每个元素删除之前整个序列的逆序对数量

    基本套路:删边变加边

    那么我们不就是求满足(pos_i<pos_j,tim_i<tim_j,num_i>num_j)的数量嘛

    先按(tim)排序,然后归并(pos_i),树状数组(num_i)

    不过这道题我们需要正反跑两个(cdq),因为我们需要分开统计(pos_i<pos_j,num_i>num_j)(pos_i>pos_j,num_i<num_j)的贡献

    但是我压缩到一个(cdq)里了(emmmm)

    需要稍微注意的一点是,我们需要把答案累加的令一个(ret_i)数组中,其中(ret_i)表示在(i)时刻新产生了多少逆序对,最后还需要输出前缀和

    不粘代码是不是太短了

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define int long long
    #define mid ((l+r)>>1)
    #define lowbit(x) ((x)&(-x))
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	const int N=1e5+10;
    	int n,m,idx,tot;
    	int pos[N];
    	int st[N];
    	int ret[N];
    	struct point
    	{
    		int x,id,tim;
    		int val;
    		inline bool operator < (const point &t) const
    		{
    			if(tim^t.tim) return tim<t.tim;
    			return id<t.id;
    		}
    	}a[N<<2],t[N<<2];
    	int tr[N<<1];
    	inline void update(int x,int k)
    	{
    		for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=k;
    	}
    	inline int query(int y)
    	{
    		int ret=0;
    		for(int i=y;i;i-=lowbit(i))
    			ret+=tr[i];
    		return ret;
    	}
    	inline void cdq(int l,int r)
    	{
    		if(l==r) return;
    		cdq(l,mid);
    		cdq(mid+1,r);
    		int tl=l,tr=mid+1,tot=l;
    		while(tl<=mid&&tr<=r)
    		{
    			if(a[tl].id<=a[tr].id) update(a[tl].x,1),t[tot++]=a[tl++];
    			else ret[a[tr].tim]+=query(n)-query(a[tr].x),t[tot++]=a[tr++];
    		}
    		while(tl<=mid) update(a[tl].x,1),t[tot++]=a[tl++];
    		while(tr<=r) ret[a[tr].tim]+=query(n)-query(a[tr].x),t[tot++]=a[tr++];
    		for(int i=l;i<=mid;++i) update(a[i].x,-1);
    		tl=mid,tr=r;
    		while(tl>=l&&tr>=mid+1)
    		{
    			if(a[tl].id>=a[tr].id) update(a[tl].x,1),--tl;
    			else ret[a[tr].tim]+=query(a[tr].x-1),--tr;
    		}
    		while(tl>=l) update(a[tl].x,1),--tl;
    		while(tr>=mid+1) ret[a[tr].tim]+=query(a[tr].x-1),--tr;
    		for(int i=l;i<=mid;++i) update(a[i].x,-1);
    		for(int i=l;i<=r;++i) a[i]=t[i];
    	}
    	inline void main()
    	{
    		n=read(),m=read();
    		for(int x,i=1;i<=n;++i)
    		{
    			x=read();
    			pos[x]=i;
    			a[i].x=x;
    			a[i].id=i;
    			a[i].tim=1;
    		}
    		for(int x,tmp,i=1;i<=m;++i)
    		{
    			x=read();
    			tmp=pos[x];
    			a[tmp].tim=m-i+2;
    		}
    		sort(a+1,a+n+1);
    		cdq(1,n);
    		for(int i=1;i<=m+1;++i) ret[i]+=ret[i-1];
    		for(int i=m+1;i>=2;--i) printf("%lld
    ",ret[i]);
    	}
    }
    signed main()
    {
    	red::main();
    	return 0;
    }
    
  • 相关阅读:
    整数
    mysql-5.7.13-win32 安装
    Flex air修改外部xml文件 (转)
    JAVA 取得当前目录的路径/Servlet/class/文件路径/web路径/url地址
    C#中&和&&的区别
    百度UEditor1.4.3编辑器和asp.net MVC 5结合
    ASP.NET MVC ajax数组,模型绑定问题。
    MEF依赖注入无法在在构造函数中使用的解决办法
    AJaxFileUpload 文件上传<pre>,json字符串为空解决方法
    C#中字符串转换为IPAdress
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12045586.html
Copyright © 2011-2022 走看看