解题思路看了官方的思路,就是前缀和的思想,做题时也想到了用前缀和,但没想到怎么才能提高效率,一点一点进步吧
做完后,各种失误,各种wa,经过n个时间的查错,终于ac啦
#include <iostream> #include <cstdio> using namespace std; const int maxn=100000+3; int s[maxn][35]; int a[maxn][35]; int head[maxn],nexvt[maxn]; int n,k; int main() { while(~scanf("%d%d",&n,&k)) { int i,tem,j,p; memset(s,0,sizeof(s)); memset(head,-1,sizeof(head)); memset(a[0],0,sizeof(a[0])); nexvt[0]=head[0];//注意这两步,不要忽略第0条记录,因为区间内包括第1条记录,需要用到记录0,前缀和吗 head[0]=0;; int maxv=0; for(i=1;i<=n;i++) { scanf("%d",&tem); int key=0; for(j=0;j<k;j++) { s[i][j]=s[i-1][j]+((tem&(1<<j))>0?1:0);//这有错啦 a[i][j]=s[i][j]-s[i][0]; key=key+a[i][j]; } if(key<0) key=-key;//注意此处key可能为负值。哎,思考的不严密啊,当一个值要作为数组下标,要注意啊 key%=maxn; int loc=-1; for(j=head[key];j!=-1;j=nexvt[j]) { for(p=0;p<k;p++) { if(a[i][p]!=a[j][p]) break; } if(p==k&&i-j>maxv) maxv=i-j;//是i-j,不是i-j+1 } nexvt[i]=head[key]; head[key]=i; } printf("%d\n",maxv); } return 0; }