ZOJ 3633 rmq 重点在于转化
生活随笔
收集整理的這篇文章主要介紹了
ZOJ 3633 rmq 重点在于转化
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:
給出了n個數(shù)..
給m個詢問..問在詢問范圍a, b內從右到左第一個出現(xiàn)重復的數(shù)..
思路:
用map求出離這個數(shù)最近的相同的數(shù)的位置..<其實不用map也可以吧~>
然后用rmq求出范圍內位置值最大的那個~如果那個位置不在給定范圍內或者最大值就是0..代表范圍內沒有重復的數(shù)~就輸出OK..
否則輸出那個數(shù)..
Tips:
用一個數(shù)組保存輸入的值..
最后就可以根據(jù)求出的最大位置..找到這個重復的數(shù)..
Code:
View Code 1 #include <stdio.h> 2 #include <cstring> 3 #include <map> 4 #include <cmath> 5 #include <iostream> 6 using namespace std; 7 #define clr(x) memset(x, 0, sizeof(x)) 8 const int M = 500010; 9 int dp[M][18]; 10 11 void makermq(int n,int b[]) 12 { 13 int i,j; 14 for(i=1;i<=n;i++) 15 dp[i][0]=b[i]; 16 for(j=1;(1<<j)<=n;j++) 17 for(i=1;i+(1<<j)-1<=n;i++) 18 dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); 19 } 20 21 int rmq(int s,int v) 22 { 23 int k=(int)(log((v-s+1)*1.0)/log(2.0)); 24 return max(dp[s][k],dp[v-(1<<k)+1][k]); 25 } 26 27 int arr[500010]; 28 int num[500010]; 29 int main() 30 { 31 int i, j, k; 32 int n, m; 33 int a, b, tmp; 34 while(cin >> n) 35 { 36 map<int, int> mm; 37 clr(dp); 38 clr(arr); 39 for(i = 1; i <= n; ++i){ 40 cin >> num[i]; 41 arr[i] = mm[num[i]]; 42 mm[num[i]] = i; 43 } 44 makermq(n, arr); 45 cin >> m; 46 while(m--) 47 { 48 cin >> a >> b; 49 tmp = rmq(a, b); 50 if(tmp == 0 || tmp < a || tmp > b) puts("OK"); 51 else printf("%d\n", num[tmp]); 52 } 53 puts(""); 54 } 55 return 0; 56 }可能能ac了~因為ZOJ今天刷得很慢~我要睡覺了..
上一次是少了個空行所以PE了~現(xiàn)在應該能ac了~
?
轉載于:https://www.cnblogs.com/Griselda/archive/2012/08/29/2662933.html
總結
以上是生活随笔為你收集整理的ZOJ 3633 rmq 重点在于转化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库开发管理中的十条建议
- 下一篇: 由验证下载服务器性能得到的启示