把原来的数组相邻两数逐个求差构造新数组,这样若a[i]!=0,只需要更新a[i+k]即可,达到o(n^2)的复杂度
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define N 100100
typedef long long ll;
using namespace std;
int a[3010],b[3010],c[3010];
int main(){
int t,T;
int i,j,k,m,n;
scanf("%d",&T);
bool vis[3010];
for(t=1;t<=T;t++){
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&b[i]);
c[1]=b[1];
for(i=2;i<=n;i++)
c[i]=(b[i]-b[i-1]+m)%m;
memset(vis,0,sizeof(vis));
for(k=n;k>=1;k--){
if(vis[k])continue;
for(i=1;i<=n;i++)a[i]=c[i];
for(i=1;i+k-1<=n;i++)
if(a[i]!=0){
a[i+k]=(a[i+k]+a[i])%m;
}
bool ok=1;
for(i;i<=n;i++){
if(a[i]!=0){
ok=0;
break;
}
}
if(ok){
vis[k]=1;
for(i=1;i<k;i++) if(k%i==0)vis[i]=1;
}
}
int ans=0;
for(i=1;i<=n;i++) if(vis[i])ans++;
printf("%d\n",ans);
}
return 0;
}