Mr. Kitayuta vs. Bamboos题解
Mr. Kitayuta vs. Bamboos题解
恶心题,不想说话。
二分,倒过来搞;
\(h[i]+m*a[i]-num*p<=x\)可推出\(h[i]<=x+num*p-m*a[i]\)
题目变为:
每根竹子原长度为\(x\),每天减少\(a[i]\)长度,每次可以添加\(p\)长度,现长度不得小于0,
贪心的选择,尽可能不添加长度,每次给最近长度就会小于0的竹子添加长度,如果最后仍小于\(h[i]\),就继续入队。
#include<bits/stdc++.h>
#define lc x<<1
#define rc x<<1|1
using namespace std;
const int N=1e5+7;
int n,q,t,t1,t2,lf,rg,LCA,LCA2,cnt=0,num=0,ansl,ansr,d[N],dfn[N],rev[N],head[N],Min[N<<2],Max[N<<2],f[N][21];
struct edge{int nxt,to;}e[N];
inline void add(int u,int v){e[++cnt].nxt=head[u],e[cnt].to=v,head[u]=cnt;}
inline int read(){
int T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
void dfs(int x,int fa){
d[x]=d[fa]+1,f[x][0]=fa,dfn[x]=++num,rev[num]=x;
for(int i=1;i<=18;++i) f[x][i]=f[f[x][i-1]][i-1];
for(int i=head[x];i;i=e[i].nxt) dfs(e[i].to,x);
}
void build(int l,int r,int x){
if(l==r){Min[x]=Max[x]=dfn[l]; return;}
int mid=l+r>>1;
build(l,mid,lc),build(mid+1,r,rc);
Max[x]=max(Max[lc],Max[rc]),Min[x]=min(Min[lc],Min[rc]);
}
int query(int l,int r,int p,int q,int x){
if(p>q) return n+1;
if(p<=l&&r<=q) return Min[x];
int mid=l+r>>1,ans=n+1;
if(p<=mid) ans=min(ans,query(l,mid,p,q,lc));
if(q>mid) ans=min(ans,query(mid+1,r,p,q,rc));
return ans;
}
int query2(int l,int r,int p,int q,int x){
if(p>q) return 0;
if(p<=l&&r<=q) return Max[x];
int mid=l+r>>1,ans=0;
if(p<=mid) ans=max(ans,query2(l,mid,p,q,lc));
if(q>mid) ans=max(ans,query2(mid+1,r,p,q,rc));
return ans;
}
int lca(int x,int y){
if(d[x]<d[y]) swap(x,y);
for(int i=18;i>=0;--i) if(d[x]>=d[y]+(1<<i)) x=f[x][i];
if(x==y) return x;
for(int i=18;i>=0;--i) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
int main(){
n=read(),q=read();
for(int i=2;i<=n;++i) t=read(),add(t,i);
d[0]=-1,dfs(1,0),build(1,n,1);
for(int i=1;i<=q;++i){
t1=read(),t2=read(),lf=rev[query(1,n,t1,t2,1)],rg=rev[query2(1,n,t1,t2,1)];
ansl=rev[min(query(1,n,t1,lf-1,1),query(1,n,lf+1,t2,1))];
ansr=rev[max(query2(1,n,t1,rg-1,1),query2(1,n,rg+1,t2,1))];
LCA=lca(ansl,rg),LCA2=lca(lf,ansr);
if(d[LCA]>d[LCA2]) printf("%d %d\n",lf,d[LCA]);
else printf("%d %d\n",rg,d[LCA2]);
}
return 0;
}