description
analysis
-
正解……桶乱搞
-
维护两个指针l,rl,rl,r,每次右移rrr一位,表示加入a[r]a[r]a[r],然后在满足条件的情况下维护lll
-
如果a[r]>=ka[r]>=ka[r]>=k,就把a[r]−ka[r]-ka[r]−k丢进桶里并记录a[r]−ka[r]-ka[r]−k最右出现的位置(因为有可能这个模数后面会出现)
-
然后枚举约数,lll对于所有约数倍的位置取最大值,就是lll合法的最左位置
-
答案每次加上r−lr-lr−l就行了
code
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 100005
#define ll long long
#define fo(i,a,b) for (register int i=a;i<=b;++i)
#define fd(i,a,b) for (register int i=a;i>=b;--i)
using namespace std;
int a[MAXN],b[MAXN];
int n,k;
ll ans;
__attribute__((optimize("-O3")))
int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0' || '9'<ch)
{
if (ch=='-')f=-1;
ch=getchar();
}
while ('0'<=ch && ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
__attribute__((optimize("-O3")))
int main()
{
freopen("drink.in","r",stdin);
freopen("drink.out","w",stdout);
n=read(),k=read();
fo(i,1,n)a[i]=read();
for (register int l=0,r=1;r<=n;++r)
{
if (a[r]>k)
{
for (register int i=0;i<=100000;i+=a[r])l=max(b[i],l);
}
ans+=r-l;
if (a[r]>=k)b[a[r]-k]=r;
}
printf("%lld\n",ans);
return 0;
}