题意: 给你K个点上面有灯,最后要求任意取连续的长度为r的段至少有2个灯,最少添加。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k,r;
ll a[100005];
ll t[400005];
ll vis[100005];
void updata(int rt,int l,int r,int L,int w)
{
if(l==r)
{
t[rt] += w;
return ;
}
int mid = (l+r)>>1;
if(L<=mid)
updata(rt<<1,l,mid,L,w);
else
updata(rt<<1|1,mid+1,r,L,w);
t[rt] = t[rt<<1]+t[rt<<1|1];
}
ll query(int rt,int l,int r,int L,int R)
{
if(L>R)
return 0;
if(L<=l&&r<=R)
{
return t[rt];
}
int mid = (l+r)>>1;
ll ans = 0;
if(L<=mid)
ans += query(rt<<1,l,mid,L,R);
if(R>mid)
ans += query(rt<<1|1,mid+1,r,L,R);
return ans;
}
int main()
{
cin>>n>>k>>r;
for(int i=0;i<k;i++)
{
cin>>a[i];
vis[a[i]]=1;
updata(1,1,n,a[i],1);
}
ll ans = 0;
for(int i=1;i+r-1<=n;i++)
{
ll tmp = query(1,1,n,i,i+r-1);
if(tmp-2<0)
{
for(int j = i+r-1;j>=i&&tmp-2<0;j--)
{
if(vis[j]==0)
{
updata(1,1,n,j,1);
vis[j]=1;
tmp++;
ans++;
}
}
}
}
cout<<ans<<endl;
return 0;
}