好神仙的数据结构题呀!
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 ",Ans[i]); return 0; }