2022春每日一题:Day 35

题目:[NOI Online #1 提高组] 冒泡排序

看到范围这么大,求逆序对,有修改,估计也只能树状数组了,考查冒泡排序性质,排第i次冒泡排序,总逆序对个数会减少i的逆序对个数,然后交换两个数,他们相对整个序列没有改变,也就是说,交换两个数,只可能是其中一个数逆序对个数+1或者-1,抓住这两点这个题就不难了。注意不开longlong见祖宗

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define int long long
#define lowbit(x) x&-x
const int N=2e5+5;
using namespace std;
int n,m,a[N],b[N],cnt,t[N];
namespace fenwick
{
	struct fw
	{
		int c;
	}e[N];
	void modify(int x,int v)
	{
		for(int i=x;i<=n;i+=lowbit(i))
		    e[i].c+=v;
	}
	int query(int x)
	{
		int ret=0;
		for(int i=x;i;i-=lowbit(i))
		    ret+=e[i].c;
		return ret;
	}
}
using namespace fenwick;
signed main()
{
	scanf("%lld %lld",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		b[i]=i-query(a[i])-1;
		cnt+=b[i];
		t[b[i]]++;
		modify(a[i],1LL);
	}
	for(int i=1;i<=n;i++)
	    e[i].c=0;
	modify(1,cnt);
	cnt=0;
	for(int i=0;i<n;i++)
	{
		cnt+=t[i];
		modify(i+2,-(n-cnt));
	}
	while(m--)
	{
		int opt,i;
		scanf("%lld %lld",&opt,&i);
		i=min(i,n-1);
		if(opt==1)
		{
			if(a[i]<a[i+1])
			{
				swap(b[i],b[i+1]);
				modify(1,1LL);
				modify(b[i+1]+2,-1LL);
				b[i+1]++;
			}
			else
			{
				swap(b[i],b[i+1]);
				modify(1,-1LL);
				b[i]--;
				modify(b[i]+2,1LL);
			}
			swap(a[i],a[i+1]);
		}
		else
		    printf("%lld\n",query(i+1));
	}
	return 0;
}
posted @   __honey  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示