CF540E:树状数组+离散化

CF540E

题解:这一题做了将近4个小时,看网上的博客,都是简单带过。

找了两个写得好的博客,帮助大家理解一下。

https://www.cnblogs.com/FinFin/p/9727351.html

https://blog.csdn.net/u011580493/article/details/45461549

代码:

#include <bits/stdc++.h>
using namespace std;
int const N = 100000 + 10;
typedef long long ll;
int n,val[N<<1],a[N],b[N],sum[N<<1],num[N<<1],tot,d[N<<1];   //记得开两倍,RE了一次
int lowbit(int x){return x&-x;}
void add(int i,int x){
	while(i <= tot){
		d[i] += x;
		i += lowbit(i);
	}
}
int query(int i){
	int sum = 0;
	while(i){
		sum += d[i];
		i -= lowbit(i);
	}
	return sum;
}
int main(){
	scanf("%d",&n);
	tot = 0;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i],&b[i]);
		num[++tot] = a[i],	num[++tot] = b[i];
	}
	sort(num+1,num+1+tot);
	tot = unique(num+1,num+1+tot) - (num+1);
	for(int i=1;i<=tot;i++)	sum[i] = sum[i-1] + num[i] - num[i-1] - 1;
	for(int i=1;i<=tot;i++)	val[i] = lower_bound(num+1,num+1+tot,num[i]) - num;
	for(int i=1;i<=n;i++){
		int k1 = lower_bound(num+1,num+1+tot,a[i]) - num;
		int k2 = lower_bound(num+1,num+1+tot,b[i]) - num;
		swap(val[k1],val[k2]);
	}
	ll ans = 0;
	memset(d,0,sizeof(d));
	for(int i=1;i<=tot;i++){
		ans += (ll)(query(tot)-query(val[i])); 
		ans += (ll)abs(sum[val[i]] - sum[i]);
		add(val[i],1);
	}
	printf("%lld\n",ans);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: \u4f7f\u7528 Python \u53ef\u4ee5\u5b9e\u73b0\u8be5\u529f\u80fd\uff1a a = [1, 7, 9, 11, 13, 15, 17, 19] b = [2, 4, 6, 8, 10] c = sorted(a + b) print(c) \u8fd9\u4e2a\u7a0b\u5e8f\u5c06 a \u548c b \u5408\u5e76\u5e76\u63d0\u53d6\u5347\u5e8f\u5f97\u5230\u65b0\u7684\u6570\u7ec4 c\uff0c\u7136\u540e\u5728\u7ed3\u679c\u4e2d\u6253\u5370\u51fa c \u3002 \u8fd9\u4e2a\u7a0b\u5e8f\u6269\u5c55\u4e86\u4e0a\u4e00\u4e2a Python \u5b9e\u73b0\u6570\u7ec4\u5408\u5e76\u7684\u7b97\u6cd5\uff0c\u4f7f\u5f97\u5f88\u5bb9\u6613\u7528\u6765\u5904\u7406\u4efb\u4f55\u6570\u7ec4\u5408\u5e76\u7684\u95ee\u9898\u3002 ### 回答2: 要实现数组合并并按升序排序,可以利用指针来操作。 首先,我们创建一个新的数组c,长度为两个数组a和b的长度之和。在这个过程中,需要用指针来遍历和操作数组元素。 然后,我们定义三个指针:指针pa指向数组a的第一个元素,指针pb指向数组b的第一个元素,指针pc指向数组c的第一个位置。 接下来,我们可以使用while循环来遍历数组a和数组b,将两个数组中的元素逐个比较,较小的元素放入数组c中,并将相应的指针向后移动一位。 具体的步骤如下: 1. 创建一个新的数组c,长度为数组a和数组b的长度之和。 2. 定义三个指针:pa指向数组a的第一个元素,pb指向数组b的第一个元素,pc指向数组c的第一个位置。 3. 利用while循环遍历数组a和数组b,直到其中一个数组已经全部遍历完。 4. 在循环中,比较指针pa和pb所指向的元素大小,较小的元素放入数组c中,并将相应的指针向后移动一位。 5. 循环结束后,说明其中一个数组已经全部遍历完毕,剩下的元素直接放入数组c中。 6. 最后,利用冒泡排序或者其他排序算法对数组c进行升序排序。 这样,就可以利用指针来实现数组合并并按升序排序了。 ### 回答3: 要利用指针来实现数组合并,首先需要定义三个指针变量,分别指向数组a、数组b和数组c的起始位置。 接下来,我们可以通过比较a指针和b指针所指向的元素大小,将较小的元素复制到c指针所指向的位置。然后,将c指针和较小元素的数组指针向后移动一位。重复这个过程,直到a或b指针超出其数组的长度。 当其中一个数组的元素全部复制到c数组后,再将另一个数组中剩余的元素依次复制到c数组中。最后,得到的数组c即为两个数组合并且按升序排序的结果。 具体的实现代码如下: ``` #include <stdio.h> void mergeArrays(int *a, int sizeA, int *b, int sizeB, int *c) { int *ptrA = a; int *ptrB = b; int *ptrC = c; while (ptrA < a + sizeA && ptrB < b + sizeB) { if (*ptrA <= *ptrB) { *ptrC = *ptrA; ptrA++; } else { *ptrC = *ptrB; ptrB++; } ptrC++; } while (ptrA < a + sizeA) { *ptrC = *ptrA; ptrA++; ptrC++; } while (ptrB < b + sizeB) { *ptrC = *ptrB; ptrB++; ptrC++; } } int main() { int a[] = {1, 7, 9, 11, 13, 15, 17, 19}; int b[] = {2, 4, 6, 8, 10}; int c[13]; mergeArrays(a, 8, b, 5, c); for (int i = 0; i < 13; i++) { printf("%d ", c[i]); } return 0; } ``` 运行结果为:1 2 4 6 7 8 9 10 11 13 15 17 19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值