zoj 3633 rmq或线段树

来源:互联网 发布:diy在线定制系统 源码 编辑:程序博客网 时间:2024/05/22 14:22


两个方法基本差不多,记住最近一次出现这个数的位置,就可以了。


RMQ :

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<map>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;const int mx=5e5+10;int n,m,num[mx],kep[mx];map <int,int> mp;int dp[mx][20];void Rmq(){for(int i=1;i<=n;i++)dp[i][0]=kep[i];for(int j=1;(1<<j)<=n;j++){for(int i=1;i+(1<<j)-1<=n;i++)dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);}}int query(int l,int r){int len=r-l+1,k=log(len)/log(2.0);return max(dp[l][k],dp[r-(1<<k)+1][k]);}int main(){while(cin>>n){mp.clear();for(int i=1;i<=n;i++){scanf("%d",num+i);kep[i]=mp[num[i]];mp[num[i]]=i;}Rmq();scanf("%d",&m);int l,r;while(m--){scanf("%d%d",&l,&r);int pos=query(l,r);if(pos<l) puts("OK");else printf("%d\n",num[pos]);}puts("");}    return 0; }


线段树:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<map>#include<cmath>#include<algorithm>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;typedef long long ll;const int mx=5e5+10;int n,m,num[mx],kep[mx],sec[mx<<2];map <int,int> mp;void push_up(int rt){sec[rt]=max(sec[rt<<1],sec[rt<<1|1]);}void build(int l,int r,int rt){if(l==r){sec[rt]=kep[l];return ;}int m=(l+r)>>1;build(lson);build(rson);push_up(rt);}int query(int l,int r,int rt,int L,int R){if(L<=l&&R>=r) return sec[rt];int m=(l+r)>>1,ans=0;if(m>=L)  ans=max(ans,query(lson,L,R));if(m<R)   ans=max(ans,query(rson,L,R));return ans;}int main(){while(cin>>n){mp.clear();for(int i=1;i<=n;i++){scanf("%d",num+i);kep[i]=mp[num[i]];mp[num[i]]=i;}build(1,n,1);scanf("%d",&m);int l,r;while(m--){scanf("%d%d",&l,&r);int pos=query(1,n,1,l,r);if(pos<l) puts("OK");else printf("%d\n",num[pos]);}puts("");}    return 0; }



0 0