Y1——ST表

知识点

ST表

只能询问,不能修改

ST表的预处理:

使用了DP的思想,设a是要求区间最值的数列,f(i,j)表示从第i个数起连续2^j个数中的最大值

状态转移方程

f [ i , j ]=max( f [ i , j-1 ], f [ i + 2 ^ j-1,j - 1])

建立ST表

void build(){//建立ST表,时间复杂度O(nlogn)

for(int i=1;i<=n;i++){

f[i][0]=a[i];

}

for(int j=1;(1<<j)<=n;j++){//枚举区间长度

for(int i=1;i+(i<<j)-1<=n;i++){//枚举区间左端点

f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);

}

}

}

查询区间信息

int query(int l,int r)//查询区间[l,r]的信息(最大值、最小值......)

int k=log2(r-l+1);

return max(f[l][k],f[r-(1<<k)+1][k]);

}

题题题题

平衡的阵容

题目描述

每天,农夫John的n(1≤n≤5×10​^4​​)头牛总是按同一序列排队。有一天, John 决定让一些牛们玩一场飞盘比赛。他准备找一群在队列中位置连续的牛来进行比赛。但是为了避免水平悬殊,牛的身高不应该相差太大。JohnJohn 准备了q(1≤q≤1.8×10^5)个可能的牛的选择和所有牛的身高hi(1≤hi≤106,1≤i≤n)h​i​​(1≤h​i​​≤10​6​​,1≤i≤n)。他想知道每一组里面最高和最低的牛的身高差。

输入格式

第一行两个数n,q。接下来n行,每行一个数hi。再接下来q行,每行两个整数a和b,表示询问第a头牛到第b头牛里的最高和最低的牛的身高差。

输出格式

输出共q行,对于每一组询问,输出每一组中最高和最低的牛的身高差。

样例输入

6 3

1

7

3

4

2

5

1 5

4 6

2 2

样例输出

6

3

0

代码

cpp 复制代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=5e4+5;
int n,q,a,b,h[N],f[N][20],f1[N][20]; 
void build(){//建立ST表,时间复杂度O(nlogn) 
	for(int i=1;i<=n;i++){
		f[i][0]=h[i];
		f1[i][0]=h[i];
	}
	for(int j=1;(1<<j)<=n;j++){//枚举区间长度 
		for(int i=1;i+(1<<j)-1<=n;i++){//枚举区间左端点 
			f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]); 
			f1[i][j]=min(f1[i][j-1],f1[i+(1<<j-1)][j-1]);
		} 
	} 
}
int query(int l,int r){//查询区间[l,r]的信息(最大值、最小值......) 
	int k=log2(r-l+1);
	int maxx=max(f[l][k],f[r-(1<<k)+1][k]);
	int minn=min(f1[l][k],f1[r-(1<<k)+1][k]);
	return maxx-minn;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>h[i];
	} 
	build();
	for(int i=1;i<=q;i++){
		cin>>a>>b;
		cout<<query(a,b)<<"\n";
	}
	return 0;
}

GCD

时间限制:2秒 内存限制:128M

题目描述

给你一个 N(N≤100,000)N(N≤100,000) 个整数序列:a1,⋯,an(0<ai≤1000,000,000)a​1​​,⋯,a​n​​(0<a​i​​≤1000,000,000)。 有 Q(Q≤100,000)Q(Q≤100,000) 个查询。 对于每个查询 l,rl,r,您必须计算 gcd(al,,al+1,⋯,ar)gcd(a​l​​,,a​l+1​​,⋯,a​r​​) 并计算对的数量(l′,r′)(1≤l<r≤N)(l′,r′)(1≤l<r≤N),使得 gcd(al′,al′+1,⋯,ar′)gcd(a​l′​​,a​l′+1​​,⋯,a​r′​​) 等于 gcd(al,al+1,⋯,ar)gcd(a​l​​,a​l+1​​,⋯,a​r​​)。

输入描述

第一行输入包含一个数字TT,代表你需要解决的测试用例的数量。

每个 casecase 的第一行包含一个数字N(N≤100,000)N(N≤100,000),表示整数的数量。

第二行包含 NN 个整数,a1,⋯,an(0<ai≤1000,000,000)a​1​​,⋯,a​n​​(0<a​i​​≤1000,000,000)。

第三行包含一个数字Q(Q≤100,000)Q(Q≤100,000),表示查询的数量。

对于接下来的 QQ 行,第 ii 行包含两个数字 ,代表 li,ril​i​​,r​i​​,代表第 ii 个查询。

输出描述

对于每个casecase,需要在开头输出"Case #t:"。(不带引号,tt表示测试用例的编号,从11开始)。

对于每个查询,您需要在一行中输出两个数字。 第一个数字代表 gcd(al,al+1,⋯,ar)gcd(a​l​​,a​l+1​​,⋯,a​r​​),第二个数字代表对 (l′,r′)(l′,r′) 的数量,使得 gcd(al′,al′+1,⋯,ar′)gcd(a​l′​​,a​l′+1​​,⋯,a​r′​​) 等于 gcd(al,al+1,⋯,ar)gcd(a​l​​,a​l+1​​,⋯,a​r​​)。

样例输入

复制代码
  1. 1
  2. 5
  3. 1 2 4 6 7
  4. 4
  5. 1 5
  6. 2 4
  7. 3 4
  8. 4 4

样例输出

复制代码
  1. Case #1:
  2. 1 8
  3. 2 4
  4. 2 4
  5. 6 1

代码

cpp 复制代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int n,t,q,a[N],f[N][19],L[N],R[N];
map<int,long long> mp;
void build(){//建立ST表,时间复杂度O(nlogn) 
	for(int i=1;i<=n;i++){
		f[i][0]=a[i];
	}
	for(int j=1;(1<<j)<=n;j++){//枚举区间长度 
		for(int i=1;i+(1<<j)-1<=n;i++){//枚举区间左端点 
			f[i][j]=__gcd(f[i][j-1],f[i+(1<<j-1)][j-1]); 
		} 
	} 
}
int query(int l,int r){//查询区间[l,r]的信息(最大值、最小值......) 
	int k=log2(r-l+1);
	return __gcd(f[l][k],f[r-(1<<k)+1][k]);
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	cin>>t;
	for(int ca=1;ca<=t;ca++){
		mp.clear();
		cout<<"Case #"<<ca<<":"<<"\n";
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		build();
		cin>>q;
		for(int i=1;i<=q;i++){
			cin>>L[i]>>R[i];
			mp[query(L[i],R[i])]=0;
		}
		for(int L=1;L<=n;L++){
			int R=L;
			while(R<=n){
				int l=R,r=n,d1=query(L,R);
				while(l<r){
					int mid=l+r+1>>1;
					if(query(L,mid)==d1){
						l=mid;
					}
					else{
						r=mid-1;
					}
				}
				if(mp.count(d1)){
					mp[d1]+=l-R+1;
				}
				R=l+1;
			}
			
		}
		for(int i=1;i<=q;i++){
				int tmp=query(L[i],R[i]);
				cout<<tmp<<" "<<mp[tmp]<<"\n";
			}
	}
	return 0;
}
相关推荐
代码AC不AC28 分钟前
【C++】类和对象【下】
开发语言·c++·类和对象·学习分享·技术交流
Leo来编程30 分钟前
算法-时间复杂度和空间复杂度
算法
Echo``34 分钟前
2:点云处理—3D相机开发
人工智能·笔记·数码相机·算法·计算机视觉·3d·视觉检测
星夜9821 小时前
C++回顾 Day5
开发语言·c++·算法
JK0x071 小时前
代码随想录算法训练营 Day37 动态规划Ⅴ 完全背包 零钱兑换
算法·动态规划
@Zeker1 小时前
C++多态详解
开发语言·c++
小羊不会c++吗(黑客小羊)1 小时前
【c++】 我的世界
c++
weixin_464078072 小时前
.NET 多线程题目汇总
算法·.net
纪元A梦2 小时前
贪心算法应用:边着色问题详解
java·算法·贪心算法
王燕龙(大卫)2 小时前
递归下降算法
开发语言·c++·算法