P4811
我觉得这题
一句话:每次询问枚举短的路线,在长的上二分,再记忆化可过。
考虑分析复杂度。记
否则,考虑每个位置被枚举了几次。因为
于是总复杂度
也讲一下二分的方法。注意到两车
代码非常清新。
code:
int n,q,c[N];
vector<int> g[N];
vector<ll> t[N];
map<pair<int,int>,int> mp;
il int getPos(int x,ll tm){
int p=upper_bound(t[x].begin(),t[x].end(),tm)-t[x].begin()-1;
return g[x][p+1]>g[x][p]?g[x][p]+tm-t[x][p]:g[x][p]-tm+t[x][p];
}
void Yorushika(){
read(n,q);
rep(i,1,n){
read(c[i]);
g[i].resize(c[i]+1),t[i].resize(c[i]+1);
rep(j,1,c[i]){
read(g[i][j]);
t[i][j]=j==1?0:t[i][j-1]+abs(g[i][j]-g[i][j-1]);
}
}
while(q--){
int x,y;read(x,y);
if(g[x].size()>g[y].size()||g[x].size()==g[y].size()&&x>y){
swap(x,y);
}
if(mp.count(Mp(x,y))){
printf("%d\n",mp[Mp(x,y)]);
continue;
}
int ans=0;
rep(i,1,c[x]-1){
if(t[x][i]>=t[y][c[y]]){
break;
}
ll l=t[x][i],r=min(t[x][i+1],t[y][c[y]]);
int u1=g[x][i],v1=getPos(y,l),u2=g[x][i+1]>g[x][i]?u1+r-l:u1-r+l,v2=getPos(y,r);
ans+=(u1>v1)^(u2>v2);
}
printf("%d\n",mp[Mp(x,y)]=ans);
}
}
signed main(){
int t=1;
//read(t);
while(t--){
Yorushika();
}
}