好神仙的数据结构题呀!
code:
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#define BL 250
#define N 100006
#define inf 0x7fffffff
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,arr[N];
namespace ST
{
int maxv[18][N],minv[18][N],bin[18];
inline void init()
{
int i,j;
for(i=0;i<18;++i) bin[i]=(1<<i);
for(i=1;i<=n+1;++i)
maxv[0][i]=minv[0][i]=arr[i];
for(i=1;i<18;++i)
for(j=1;j+bin[i]-1<=n+1;++j)
{
maxv[i][j]=max(maxv[i-1][j],maxv[i-1][j+bin[i-1]]);
minv[i][j]=min(minv[i-1][j],minv[i-1][j+bin[i-1]]);
}
}
inline int q_max(int l,int r)
{
int p=log2(r-l+1);
return max(maxv[p][l],maxv[p][r-bin[p]+1]);
}
inline int q_min(int l,int r)
{
int p=log2(r-l+1);
return min(minv[p][l],minv[p][r-bin[p]+1]);
}
inline int query(int l,int r) { return q_max(l,r)-q_min(l,r); }
};
namespace LCT
{
#define lson s[x].ch[0]
#define rson s[x].ch[1]
int sta[N];
struct data
{
int ch[2],rev,f,siz;
}s[N];
inline int get(int x) { return s[s[x].f].ch[1]==x; }
inline int isr(int x) { return s[s[x].f].ch[0]!=x&&s[s[x].f].ch[1]!=x; }
inline void pushup(int x)
{
s[x].siz=s[lson].siz+s[rson].siz+1;
}
inline void rotate(int x)
{
int old=s[x].f,fold=s[old].f,which=get(x);
if(!isr(old))
s[fold].ch[s[fold].ch[1]==old]=x;
s[old].ch[which]=s[x].ch[which^1];
if(s[old].ch[which])
s[s[old].ch[which]].f=old;
s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold;
pushup(old),pushup(x);
}
inline void mark(int x)
{
swap(lson,rson);
s[x].rev^=1;
}
inline void pushdown(int x)
{
if(s[x].rev)
{
if(lson)
mark(lson);
if(rson)
mark(rson);
s[x].rev=0;
}
}
inline void splay(int x)
{
int u=x,v=0,fa;
for(sta[++v]=u;!isr(u);u=s[u].f)
sta[++v]=s[u].f;
for(;v;--v)
pushdown(sta[v]);
for(u=s[u].f;(fa=s[x].f)!=u;rotate(x))
if(s[fa].f!=u)
rotate(get(fa)==get(x)?fa:x);
}
inline void Access(int x)
{
for(int y=0;x;y=x,x=s[x].f)
splay(x),rson=y,pushup(x);
}
inline void link(int x,int y) { s[y].f=x; }
// 断掉 y 与父亲
inline void cut(int y)
{
Access(y),splay(y);
s[s[y].ch[0]].f=0,s[y].ch[0]=0,pushup(y);
}
inline int frt(int x)
{
while(lson)
x=lson;
return x;
}
#undef lson
#undef rson
};
struct ask
{
int k,id;
bool operator<(const ask b) const { return k<b.k; }
}q[N];
int h[N],mark[N],A[N],Ans[N];
vector<int>G[N];
int find(int x,int k)
{
int l=x+1,r=n+1,mid;
for(mid=(l+r)>>1;l<r;mid=(l+r)>>1)
{
int cu=ST::query(x,mid);
if(cu>k)
r=mid;
else
l=mid+1;
}
return mid;
}
int main()
{
// setIO("input");
int i,j,B,W,Q;
scanf("%d%d%d",&n,&W,&Q);
B=sqrt(n);
for(i=1;i<=n;++i)
scanf("%d",&arr[i]);
arr[n+1]=inf;
ST::init();
for(i=1;i<=n;++i)
LCT::s[i].siz=1;
for(i=1;i<=Q;++i)
{
scanf("%d",&q[i].k);
A[i]=q[i].k=W-q[i].k,q[i].id=i;
}
sort(q+1,q+1+Q);
for(i=1;i<=n;++i)
h[i]=i,LCT::s[i].f=i+1,G[1].push_back(i);
for(i=1;i<=Q;++i)
{
int o,t,k;
for(o=j=0;j<G[i].size();++j)
{
int u=G[i][j];
LCT::cut(u);
for(k=h[u]+1;ST::query(u,k)<=q[i].k&&k-u<=B&&k<=n;++k);
if(k-u>B)
mark[u]=1;
else
{
h[u]=k;
LCT::s[u].f=h[u];
G[lower_bound(q+1,q+1+Q,(ask){ST::query(u,h[u]),0})-q].push_back(u);
}
}
for(j=1;;j=find(j,q[i].k),++o)
{
if(!mark[j])
{
LCT::Access(j);
LCT::splay(j);
o+=LCT::s[j].siz-1;
j=LCT::frt(j);
}
if(j>n)
break;
}
Ans[q[i].id]=o-1;
}
for(i=1;i<=Q;++i)
printf("%d\n",Ans[i]);
return 0;
}