这题其实不难啊,为啥没人写.
理解完题意,首先预处理应该都会.然后考虑如何统计答案.直接想到一个暴力的方法:O(n^2)枚举左右端点,O(k)判断是否各个位置上的数都相同.
然后考虑如何把一个n改成一个log(n)?k比较小,可以往这边考虑
先考虑下面两个例子.这里每一位表示1,i时出现1的总数.
o[i].a[j]2 3 5 1 o[f].a[j]7 8 10 6
这两个端点显然合法.如何描述这种"相同性"呢?我有两种方法.一种是都减去minn(a[j]),得到这样的结果.
都减1 1 2 4 0 都减6 1 2 4 0
或者弄一个差分数组.原来是j∈[1,k],差分数组显然只需要[2,k]相同即可.
差分 ? 1 2 -4
然后如何更新答案呢?我想到了三行离散化.但是应该还有一种更好的方法:map.直接用结构体做下标还不是美滋滋?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using namespace std; int i,f,tt; int n,k,ans; struct node{ int a[40],sum[40]; friend bool operator <(node x,node y){ for(int d=2;d<=k;d++){ if(x.a[d]!=y.a[d]) return x.a[d]<y.a[d]; } return 0; } }o[100000]; map<node,int>mm; int main() { n=read();k=read(); if(k==1){cout<<n;return 0;} mm[o[0]]=1;//记录全0的时候的下标为1 for(i=1;i<=n;i++){ tt=read(); for(f=1;f<=k;f++){ o[i].sum[f]=o[i-1].sum[f]+tt%2; tt=tt/2; } for(f=2;f<=k;f++) o[i].a[f]=o[i].sum[f]-o[i].sum[f-1];//差分数组 tt=mm[o[i]]; if(tt!=0) ans=max(ans,i-tt+1);//更新答案 else mm[o[i]]=i+1;//记录最先出现的下标.为了照顾o[0]只好赋为下标+1 } cout<<ans; return 0; }