生活随笔
收集整理的這篇文章主要介紹了
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;}```
```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;}```
```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]);}}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算法模板)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。