#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL MAXN=1e5+5;
const LL MOD=1e9+7;
LL n,p,a[MAXN];
LL blksiz,blkcnt,pre[MAXN],nxt[MAXN],id[MAXN];
LL add[MAXN],val[325][325],sum[325][325];
LL blg[MAXN],ll[MAXN],rr[MAXN],f[MAXN];
struct node{
LL x,id;
bool operator <(const node &t)const{
return x<t.x||(x==t.x&&id<t.id);
}
}blk[325][325];
void addv(LL l,LL r,LL id,LL v){
LL siz=rr[id]-ll[id]+1;
for(LL i=1;i<=siz;i++){
if(blk[id][i].id>=l&&blk[id][i].id<=r){
blk[id][i].x+=v;
}
}
sort(blk[id]+1,blk[id]+siz+1);
for(LL i=1;i<=siz;i++){
val[id][i]=f[blk[id][i].id-1];
sum[id][i]=(sum[id][i-1]+val[id][i])%MOD;
}
}
void ADD(LL l,LL r,LL v){
if(blg[l]==blg[r]){
addv(l,r,blg[l],v);
return ;
}
LL bl=1,br=blkcnt;
if(l==ll[blg[l]])bl=blg[l];
else bl=blg[l]+1;
if(r==rr[blg[r]])br=blg[r];
else br=blg[r]-1;
for(LL i=bl;i<=br;i++)add[i]+=v;
if(l!=ll[blg[l]])addv(l,rr[blg[l]],blg[l],v);
if(r!=rr[blg[r]])addv(ll[blg[r]],r,blg[r],v);
}
LL ask(LL l,LL r,LL id){
LL res=0;
LL siz=rr[id]-ll[id]+1;
for(LL i=1;i<=siz;i++){
if(blk[id][i].id>=l&&blk[id][i].id<=r){
if(blk[id][i].x+add[id]<=p){//
res=(res+val[id][i])%MOD;
}
}
}
return res;
}
LL query(LL l,LL r){
LL res=0;
if(blg[l]==blg[r])return ask(l,r,blg[l]);
LL bl=1,br=blkcnt;
if(l==ll[blg[l]])bl=blg[l];
else bl=blg[l]+1;
if(r==rr[blg[r]])br=blg[r];
else br=blg[r]-1;
for(LL i=bl;i<=br;i++){
LL siz=rr[i]-ll[i]+1;
LL l=1,r=siz,pos=0;
while(l<=r){
LL mid=(l+r)>>1;
if(blk[i][mid].x+add[i]<=p){
pos=mid;l=mid+1;
}else{
r=mid-1;
}
}
res=(res+sum[i][pos])%MOD;
}
if(l!=ll[blg[l]])res=(res+ask(l,rr[blg[l]],blg[l]))%MOD;
if(r!=rr[blg[r]])res=(res+ask(ll[blg[r]],r,blg[r]))%MOD;
return res;
}
void update(LL x){
LL now=blg[x+1];
LL siz=rr[now]-ll[now]+1;
for(LL i=1;i<=siz;i++){
if(blk[now][i].id==x+1){
val[now][i]=f[x];
break;
}
}
for(LL i=1;i<=siz;i++){
sum[now][i]=(sum[now][i-1]+val[now][i])%MOD;
}
}
int main(){
freopen("home.in","r",stdin);
freopen("home.out","w",stdout);
scanf("%lld%lld",&n,&p);
for(LL i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
blksiz=sqrt(n);
for(LL i=1;i<=n;i++)id[i]=0;
for(LL i=1;i<=n;i++)pre[i]=id[a[i]],id[a[i]]=i;
for(LL i=1;i<=n;i++)id[i]=n+1;
for(LL i=n;i>=1;i--)nxt[i]=id[a[i]],id[a[i]]=i;
for(LL i=1;i<=n;i++)blg[i]=(i-1)/blksiz+1;
blkcnt=blg[n];
for(LL i=1;i<=blkcnt;i++)ll[i]=(i-1)*blksiz+1,rr[i]=min(n,i*blksiz);
for(LL i=1;i<=blkcnt;i++){
for(LL j=1;j<=rr[i]-ll[i]+1;j++){
blk[i][j]={0ll,ll[i]+j-1};
}
}
f[0]=1;
update(0);
for(LL i=1;i<=n;i++){
ADD(pre[i]+1,i,1);
if(pre[i]>=1&&pre[i]<=n)ADD(pre[pre[i]]+1,pre[i],-1);
f[i]=query(1,i);
update(i);
}
printf("%lld",f[n]);
}
分块模板代码(自用)
最新推荐文章于 2024-10-09 22:28:58 发布