Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
本题RMQ解法,附AC代码将RMQ递推公式修改下,best[i][j]=max(best[i-1][j],best[i-1][j+(1<<(i-1)),j-1+(1<<(i-1))向两边最多能扩展的长度,j+(1<<(i-1))向两边最多能扩展的长度) 求向两边最多能扩展的长度要用二分搜索来实现,然后最好能将检索的结果记录在数组中,如果下次进行同样的检索直接查表(如果不进行这样的处理C++1500ms能过,G++就TLE了),详细的看代码吧,我代码应该写的很清楚了 Source Code Problem: 3368 User: yzhw Memory: 8688K Time: 594MS Language: C++ Result: Accepted Source Code # define maxn 100005 # include <cstdio> # include <cstring> int RMQ[maxn],mm[maxn]; int best[20][maxn]; int minrefer[maxn*2],maxrefer[maxn*2]; int min(int a,int b) { return a<b?a:b; } inline int max(int a,int b) { return a>b?a:b; } inline int max(int a,int b,int c,int d) { return max(max(a,b),max(c,d)); } int low(int n,int pos) { if(minrefer[pos+100000]) return minrefer[pos+100000]; int s=1,e=n; while(s<=e) { int mid=(s+e)/2; if(pos<=RMQ[mid]) e=mid-1; else s=mid+1; } minrefer[pos+100000]=s; return s; } int high(int n,int pos) { if(maxrefer[pos+100000]) return maxrefer[pos+100000]; int s=1,e=n; while(s<=e) { int mid=(s+e)/2; if(pos>=RMQ[mid]) s=mid+1; else e=mid-1; } maxrefer[pos+100000]=e; return e; } void initRMQ(int n) { int i,j,a,b; for(mm[0]=-1,i=1;i<=n;i++) mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1]; for(i=1;i<=n;i++) best[0][i]=1; for(i=1;i<=mm[n];i++) for(j=1;j<=n+1-(1<<i);j++) { a=best[i-1][j]; b=best[i-1][j+(1<<(i-1))]; best[i][j]=max(a,b,min(j+(1<<(i))-1,high(n,RMQ[j+(1<<(i-1)-1)]))-max(low(n,RMQ[j+(1<<(i-1))-1]),j)+1,min(j+(1<<(i))-1,high(n,RMQ[j+(1<<(i-1))]))-max(low(n,RMQ[j+(1<<(i-1))]),j)+1); } return; } int askRMQ(int a,int b,int n) { int t; int oa=a,ob=b; t=mm[b-a+1];b-=(1<<t)-1; a=best[t][a];b=best[t][b]; return max(a,b,min(ob,high(n,RMQ[oa+(1<<t)-1]))-max(low(n,RMQ[oa+(1<<t)-1]),oa)+1,min(ob,high(n,RMQ[ob-(1<<t)+1]))-max(low(n,RMQ[ob-(1<<t)+1]),oa)+1); } int main() { // freopen("frequent.in","r",stdin); // freopen("ans.txt","w",stdout); while(true) { int n,q; scanf("%d",&n); if(!n) break; scanf("%d",&q); for(int i=1;i<=n;i++) scanf("%d",RMQ+i); memset(minrefer,0,sizeof(minrefer)); memset(maxrefer,0,sizeof(maxrefer)); initRMQ(n); for(int i=1;i<=q;i++) { int a,b; scanf("%d%d",&a,&b); printf("%d\n",askRMQ(a<b?a:b,a>b?a:b,n)); } } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator