日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

1470: 区间求最值(RMQ问题,ST算法模板)

發布時間:2024/9/3 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1470: 区间求最值(RMQ问题,ST算法模板) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1470: 區間求最值
Time Limit: 1 Sec Memory Limit: 128 MB
[Submit][Status][Web Board]
Description

給定一個長度為N 的數組,有q個詢問,每個詢問是求在數組的一段區間內那個元素的因子的個數最大,比如24的因子的個數就是8。

Input

首先是一個整數t,表示有t組測試數據,每組測試數據的第一行是一個整數N(1<=N<=106),第二行有N個整數ai(1<=ai<=106,i=1,2,…N)表示數組的元素。第三行有一個整數q(1<=q<=10^5),代表有q個詢問,接下來每一行有兩個整數,li,ri(li<=ri,li>=1,ri<=N).代表數組的一段區間,并且li+1>=li,ri+1>=ri。

Output

對于每組數據的每個詢問都輸出一個整數表示在這段區間里面元素因子個數的最大值。

Sample Input

1
10
2 3 5 6 9 11 12 36 39 44
3
2 6
3 8
3 9

Sample Output

4
9
9

HINT

Source
/*
常規方法:
類素數篩法統計數據范圍內每個數因子個數
然后直接區間遍歷
這時:如果你用c++的cin和cout輸入輸出,你會發現Time limit exceed
然而用c的scanf和printf輸入輸出卻AC了,雖然效率很低(應該是測試數據比較水)。
剛才和一起做題的小伙伴討論了一下這個問題,聽說C++輸入輸出可以加兩行代碼,使它輸入輸出更快:ios::sync_with_stdio(0);cin.tie(0);`但是我測試了還是不行,依然時間超限。所以對于大數據最好還是使用C語言的輸入輸出好!!
*/
//暴力AC代碼:

#include <stdio.h>#include <algorithm>using namespace std;const int n = 1e6 + 2;int a[n],b[n];int getmax(int l,int r){int y = 0;for(int i = l; i <= r; i++)y = max(y,b[i]);return y;}int main(){for(int i = 1; i <= 1e6; i++){for(int j = i; j <= 1e6; j+=i){a[j]++;}}int t,N,num;scanf("%d",&t);while(t--){scanf("%d",&N);for(int i = 1; i <= N; i++){scanf("%d",&num);b[i] = a[num];}int q;scanf("%d",&q);while(q--){int li,ri;scanf("%d%d",&li,&ri);printf("%d\n",getmax(li,ri));}}return 0;}``` //更高效的AC代碼(空間換時間) /* ST算法(Sparse Table) */ ```c#include<stdio.h>#include<algorithm>using namespace std;#define MAX 1000002#define N 30int Log[MAX],ans[MAX][N],a[MAX];int n,que,x,y;int main(){for(int i = 1; i <= 1e6; i++){for(int j = i; j <= 1e6; j+=i){a[j]++;}}int c,T;scanf("%d",&T);while(T--){scanf("%d",&n);Log[0] = -1;int num;for(int i = 1; i <= n; i++){scanf("%d",&num);ans[i][0] = a[num];Log[i] = Log[i>>1]+1;}for(int j = 1; j <= N; j++){for(int i = 1; i+(1<<j)-1<=n; i++){ans[i][j] = max(ans[i][j-1],ans[i+(1<<j-1)][j-1]);}}scanf("%d",&que);while(que--){scanf("%d%d",&x,&y);int temp = Log[y-x+1];printf("%d\n",max(ans[x][temp],ans[y-(1<<temp)+1][temp]));}}return 0;}``` /* ST算法模板 */ ```c#include<stdio.h>#include<algorithm>using namespace std;#define MAX 1000005#define N 30int Log[MAX],ans[MAX][N],num[MAX];int n,que,x,y;int main(){int i,j,c,T;scanf("%d",&T);while(T--){scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&num[i]);}Log[0]=-1;for(i=1;i<=n;i++){ans[i][0]=num[i];Log[i]=Log[i>>1]+1;}for(j=1;j<=N;j++){for(i=1;i+(1<<j)-1<=n;i++){ans[i][j]=max(ans[i][j-1],ans[i+(1<<j-1)][j-1]);//若求最小值就是min()}}scanf("%d",&que);while(que--){scanf("%d%d",&x,&y);int temp=Log[y-x+1];printf("%d\n",max(ans[x][temp],ans[y-(1<<temp)+1][temp]));}}return 0;} /* 用樹狀數組解決,待找出問題代碼 */ ```c#include <stdio.h>#include <algorithm>using namespace std;const int n = 1e6 + 2;int a[n],b[n],N,c[n];int lowbit(int x){return x&-x;}void update_max(int x,int k){for(int i = x; i <= N; i+=lowbit(i)){c[i] = max(k,c[i]);}}int getmax(int l,int r){int y = a[b[r]];while(1){y = max(y,a[b[r]]);if(l == r) break;for(r--; r-l >= lowbit(r); r-=lowbit(r))y = max(y,c[r]);}return y;}int main(){for(int i = 1; i <= 1e6; i++){for(int j = i; j <= 1e6; j+=i){a[j]++;}}int t;scanf("%d",&t);while(t--){scanf("%d",&N);for(int i = 1; i <= N; i++){scanf("%d",&b[i]);update_max(i,a[b[i]]);}int q;scanf("%d",&q);while(q--){int li,ri;scanf("%d%d",&li,&ri);printf("%d\n",getmax(li,ri));}}return 0;}

總結

以上是生活随笔為你收集整理的1470: 区间求最值(RMQ问题,ST算法模板)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。