题目
思路:
以例3为例
其r=3,可以看出,g(i)是以r长度的递增序列(最后的9那里是因为长度不够了,要特判)
f(i)是以输入值下标为标志的递增序列
先以f(i)为单位分段:for(int i=0;i<=n;i++)
在a[i]~a[i+1]-1内,fx不变为i;
再以g(i)为单位分段:for(int j=a[i];j<=a[i+1]-1;j=j+dr)
在每个r长度内,gx不变为x/r;
同时注意边界处理,当j+dr-1>a[i+1]-1
时,及时更新长度
代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,l;
int a[N];
int main()
{
cin>>n>>l;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[0]=0;
a[n+1]=l;
int r=l/(n+1);
int fx=0,gx=0;
int flag=0;
int dr=r;
int drr=0;
long long ans=0;
for(int i=0;i<=n;i++)
{
fx=i;
for(int j=a[i];j<=a[i+1]-1;j=j+dr)
{
gx=j/r;
int p=abs(fx-gx);
if(flag==0)//判断是否是最后一段
{
dr=r;
}
else
{
dr=drr;
flag=0;
}
if(j+dr-1<=a[i+1]-1)
{
ans+=dr*p;
}
if(j+dr-1>a[i+1]-1)//下一段是最后一段
{
ans+=p*(a[i+1]-j);
drr=dr-(a[i+1]-j);
flag=1;
}
}
}
cout << ans << endl;
return 0;
}