这题很坑爹,先说说题意:就是找从头开始每k个的最大值,最小值,很容易的想到了rmq,不过我今天是练习单调队列,写完后一交,tle。。。我当时以为有死循环,后面确定没有后就去看discuss,人家说G++超时,c++能过,一交果然A了,百思不得其解,后面想写一下rmq看看超不超,不会写线段树,只能用倍增的dp去做,发现数组过大,爆内存。。。后来在discuss里面发现了优化方法,对了就是滚动数组,看来我还是没有学会学以致用。改完后去交,还是tle这是神马原因,改成C++又过了比单调队列慢一点,代码量和空间都大,还是用单调队列好。
Run ID | User | Problem | Result | Memory | Time | Language | Code Length | Submit Time |
9128755 | 201030720425 | 2823 | Accepted | 7068K | 5485MS | C++ | 1048B | 2011-08-10 19:35:37 |
9128735 | 201030720425 | 2823 | Accepted |
11940K | 5891MS | C++ | 1429B | 2011-08-10 19:34:36 |
#include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; struct queuey { int key,flag; }q[1000005],qq[1000005]; int r,f,rr,ff; int insertq(int flag,int key) { while(r>f&&key<q[r].key) r--; q[++r].flag=flag; q[r].key=key; return 1; } int insertqq(int flag,int key) { while(rr>ff&&key>qq[rr].key) rr--; qq[++rr].flag=flag; qq[rr].key=key; return 1; } void init() { r=f=0; rr=ff=0; } int q1[1000005],q2[1000005]; int main() { int n,k,key,flag=0; scanf("%d%d",&n,&k); init();flag=0; for(int i=1;i<=k&&i<=n;i++) { scanf("%d",&key); insertq(i,key); insertqq(i,key); } q1[flag]=q[f+1].key; q2[flag++]=qq[ff+1].key; for(int i=k+1;i<=n;i++) { scanf("%d",&key); insertq(i,key); insertqq(i,key); while(q[f+1].flag<=i-k&&f<r) f++; while(qq[ff+1].flag<=i-k&&ff<rr) ff++; q1[flag]=q[f+1].key; q2[flag++]=qq[ff+1].key; } for(int i=0;i<flag-1;i++) printf("%d ",q1[i]); printf("%d\n",q1[flag-1]); for(int i=0;i<flag-1;i++) printf("%d ",q2[i]); printf("%d\n",q2[flag-1]); return 0; }
#include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; int dp[1000000][2],n,m,a[1000000],key; int rmq(int m) { for(int i=0;i<n;i++) dp[i][0]=a[i]; for(int k=1;k<=key;k++) for(int i=0;i+(1<<k)-1<n;i++) { dp[i][k%2]=max(dp[i][(k-1)%2],dp[i+(1<<(k-1))][(k-1)%2]); } if(n<m) { int ans=max(dp[0][key%2],dp[n-(1<<key)][key%2]); printf("%d\n",ans); } else { for(int i=0;i+m-1<n-1;i++) { int ans=max(dp[i][key%2],dp[i+m-(1<<key)][key%2]); printf("%d ",ans); } int ans=max(dp[n-m][key%2],dp[n-(1<<key)][key%2]); printf("%d\n",ans); } return 1; } int rmq1(int m) { for(int i=0;i<n;i++) dp[i][0]=a[i]; for(int k=1;k<=key;k++) for(int i=0;i+(1<<k)-1<n;i++) { dp[i][k%2]=min(dp[i][(k-1)%2],dp[i+(1<<(k-1))][(k-1)%2]); } if(n<m) { int ans=min(dp[0][key%2],dp[n-(1<<key)][key%2]); printf("%d\n",ans); } else { for(int i=0;i+m-1<n-1;i++) { int ans=min(dp[i][key%2],dp[i+m-(1<<key)][key%2]); printf("%d ",ans); } int ans=min(dp[n-m][key%2],dp[n-(1<<key)][key%2]); printf("%d\n",ans); } return 1; } int main() { int m; scanf("%d%d",&n,&m); if(n<m) key=(int)(log((n)*1.0)/log(2.0)); else key=(int)(log((m-1)*1.0)/log(2.0)); for(int i=0;i<n;i++) scanf("%d",&a[i]); rmq1(m); rmq(m); return 0; }