分治法基础题型

本文通过51Nod和CodeForces等平台的编程题目,介绍了分治法在逆序数、快速幂、二分查找等算法问题中的应用。详细解析了A到J共9道题目,涉及逆序数计算、快速幂求模运算、涂色问题、乘法表、二分查找、递减函数、非等差序列构造、四数之和为零、不规则扩展和蚂蚁问题的解题思路,并给出了相应的代码实现。
摘要由CSDN通过智能技术生成

A - 逆序数 51Nod - 1019

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

Input
第1行:N,N为序列的长度(n <= 50000) 第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)

Output
输出逆序数

Sample Input
4
2
4
3
1

Sample Output
4

解题思路:
这题主要考查归并排序,归并排序是将数列 s[l,r]分成两半 s[l,mid]和s[mid+1,r]分别进行归并排序,然后再将这两半合并起来。在合并的过程中(设l<=i<=mid,mid+1<=j<=r),当 s[i]<=s[j]时,并不产生逆序数;当 s[i]>s[j]时,在前半部分中比 s[i]大的数都比 s[j]大,将 s[j]放在 s[i]前面的话,逆序数要加上 mid+1-i。因此,可以在归并排序中的合并过程中计算逆序数。

代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int Max_n=1e5+10;
int n;
ll sum=0;//标记有多少个逆序数
int s[Max_n],d[Max_n];//d[Max_n]为临时数组
void Merge(int l,int mid,int r) {
   //两边都已排好序的数组
	int k=l;//临时下标
	int i=l,j=mid+1;//i、j 分别为开头
	while(i<=mid&&j<=r) {
   //只要有一个到头就结束了
		if(s[i]<=s[j])//右边小于左边
			d[k++]=s[i++];//直接把右边的数存入临时数组
		else {
   //右边大于左边
			d[k++]=s[j++];//左边的数放入临时数组
			sum+=mid-i+1;//因为右边大于左边,在前半部分中比 s[i]大的
			数都比 s[j]}
	}
//没有到头的继续放到后面
	while(i<=mid)
		d[k++]=s[i++];
	while(j<=r)
		d[k++]=s[j++];
	for(int i=l; i<=r; i++)//临时数组元素放回原数组
		s[i]=d[i];
}
void MergeSort(int s,int t) {
   
	if(s>=t) return;
	int mid=(s+t)>>1;//寻找中点
	MergeSort(s,mid);//递归求解:把两半元素分别排序
	MergeSort(mid+1,t);//递归求解:把两半元素分别排序
	Merge(s,mid,t);//合并问题:把两个有序表合并成一个
//将较小的元素放入临时数组
}
int main() {
   
	cin>>n;
	for(int i=0; i<n; i++)
		cin>>s[i];
	MergeSort(0,n-1);//归并排序求逆序数对
	cout<<sum<<endl;
	return 0;
}

B - A^B Mod C 51Nod - 1046

给出3个正整数A B C,求A^B Mod C。例如,3 5 8,3^5 Mod 8 = 3。

Input
3个正整数A B C,中间用空格分隔。(1 <= A,B,C <= 10^9)

Output
输出计算结果

Sample Input
3 5 8

Sample Output
3
解题思路:
这题主要考查快速幂,注意用 long long。

代码如下:

#include<stdio.h>
using namespace std;
int main() {
   
	long long a,b,c;
	scanf("%lld%lld%lld",&a,&b,&c);
	long long sum=1;
	a=a%c;
	while(b) {
   
		if(b%2!=0)//b 为奇数时
			sum=sum*a%c;
		a=a*a%c;
		b=b/2;
	}
	printf("%lld",sum);
	return 0;
}

C - Painting Fence CodeForces - 448C

Bizon the Champion isn’t just attentive, he also is very hardworking.

Bizon the Champion decided to paint his old fence his favorite color, orange. The fence is represented as n vertical planks, put in a row. Adjacent planks have no gap between them. The planks are numbered from the left to the right starting from one, the i-th plank has the width of 1 meter and the height of ai meters.

Bizon the Champion bought a brush in the shop, the brush’s width is 1 meter. He can make vertical and horizontal strokes with the brush. During a stroke the brush’s full surface must touch the fence at all the time (see the samples for the better understanding). What minimum number of strokes should Bizon the Champion do to fully paint the fence? Note that you are allowed to paint the same area of the fence multiple times.

Input
The first line contains integer n (1 ≤ n ≤ 5000) — the number of fence planks. The second line contains n space-separated integers a1, a2, …, an (1 ≤ ai ≤ 109).

Output
Print a single integer — the minimum number of strokes needed to paint the whole fence.

Examples
Input
5
2 2 1 2 1
Output
3
Input
2
2 2
Output
2
Input
1
5
Output
1
Note
In the first sample you need to paint the fence in three strokes with the brush: the first stroke goes on height 1 horizontally along all the planks. The second stroke goes on height 2 horizonta

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值