我们记录两个指针$l,r$
每一次加入一个新的$r$的时候,判断是否有模它余$k$的数,有的话就不断$++l$
然后只要每一次加上$r-l$即可
别忘了加上所有点单独成数组的情况
1 //minamoto 2 #include<bits/stdc++.h> 3 #define ll long long 4 using namespace std; 5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 6 char buf[1<<21],*p1=buf,*p2=buf; 7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 8 inline int read(){ 9 #define num ch-'0' 10 char ch;bool flag=0;int res; 11 while(!isdigit(ch=getc())) 12 (ch=='-')&&(flag=true); 13 for(res=num;isdigit(ch=getc());res=res*10+num); 14 (flag)&&(res=-res); 15 #undef num 16 return res; 17 } 18 const int N=100005; 19 int a[N],t[N],n,k,l,r,mx;ll res=0; 20 int main(){ 21 // freopen("testdata.in","r",stdin); 22 freopen("drink.in","r",stdin); 23 freopen("drink.out","w",stdout); 24 n=read(),k=read(); 25 for(int i=1;i<=n;++i) cmax(mx,a[i]=read()); 26 l=r=1,++t[a[1]],res=n; 27 while(++r<=n){ 28 if(a[r]>k){ 29 for(int i=0;i<=mx;++i){ 30 int j=i*a[r]+k; 31 if(j>mx) break; 32 while(t[j]) --t[a[l++]]; 33 } 34 } 35 ++t[a[r]]; 36 res+=r-l; 37 } 38 printf("%lld\n",res); 39 return 0; 40 }