luogu P7894 『JROI-3』1÷0
题面传送门
真就口胡一时爽,写题火葬场呗。细节真nm多。
我们考虑如果正着维护,模拟跳的过程似乎不太好维护,所以考虑反着搞,让不能接下去跳的位置去找棋子。
容易发现形如3 5 8
中的7
位置是不能跳下去的。
然后剩下的就是写个懒标记然后两个双端队列模拟就好了。
时间复杂度\(O(n+qlogn)\)
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define RI re int
#define ll long long
#define db double
#define lb long db
#define N 3000000
#define M 300000
#define mod 998244353
#define Mod (mod-1)
#define eps (1e-5)
#define U unsigned int
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define d(x,y) (n*(x-1)+(y))
#define R(n) (rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
using namespace std;
int n,m,Ans[M+5],H[2],T[2],No,La,y,un,wn,l,r,mid;ll x,A[N+5],L1,L2,F[2];const ll INF=2e18;
struct IO{
static const int S=1<<21;
char buf[S],*p1,*p2;int st[105],Top;
~IO(){clear();}
inline void clear(){fwrite(buf,1,Top,stdout);Top=0;}
inline void pc(const char c){Top==S&&(clear(),0);buf[Top++]=c;}
inline char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
inline IO&operator >> (char&x){while(x=gc(),x==' '||x=='\n'||x=='\r');return *this;}
template<typename T>inline IO&operator >> (T&x){
x=0;bool f=0;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f^=1;ch=gc();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=gc();
f?x=-x:0;return *this;
}
inline IO&operator << (const char c){pc(c);return *this;}
template<typename T>inline IO&operator << (T x){
if(x<0) pc('-'),x=-x;
do{st[++st[0]]=x%10,x/=10;}while(x);
while(st[0]) pc('0'+st[st[0]--]);return *this;
}
}fin,fout;
struct Ques{ll x;int id;};vector<Ques> S[N+50];
struct yyy{ll w;int id;}Q[2][N+50];
int main(){
freopen("1.in","r",stdin);freopen("1.out","w",stdout);
int i,j;fin>>n>>m;for(i=1;i<=n;i++) fin>>A[i];A[0]=-INF;A[++n]=INF;for(i=1;i<=m;i++) fin>>x,y=lower_bound(A+1,A+n+1,x)-A,S[y-1].push_back((Ques){x,i});
Q[0][H[0]=T[0]=n+10]=Q[1][H[1]=T[1]=n+10]=(yyy){INF,0};for(i=1;i<n;i++){
No=i&1;La=No^1;L1=A[i]-A[i-1]-1;L2=A[i+1]-A[i]-1;
if(L1>L2) {
while(H[No]<T[No]&&Q[No][H[No]].w+F[No]<=L1-L2) H[No]++;F[No]-=L1-L2;
while(H[La]<T[La]&&Q[La][T[La]-1].w+F[La]>=L2) T[La]--;Q[La][T[La]].w=L2-F[La];
}
if(L1<L2){
Q[No][--H[No]]=(yyy){-F[No],i};F[No]+=L2-L1;
}
for(j=0;j<S[i].size();j++){
l=H[No]-1;r=T[No];while(l+1<r)mid=l+r>>1,(Q[No][mid].w+F[No]>=A[i+1]-S[i][j].x?r:l)=mid;if(H[No]>T[No])un=0;else un=Q[No][r].id;
l=H[La]-1;r=T[La];while(l+1<r)mid=l+r>>1,(Q[La][mid].w+F[La]>=S[i][j].x-A[i]?r:l)=mid;if(H[La]>T[La])wn=0;else wn=Q[La][r].id;Ans[S[i][j].id]=i-max(un,wn);
}
}for(i=1;i<=m;i++) fout<<Ans[i]<<'\n';
}