P10198 题解
DaiRuiChen007 · · 题解
Problem Link
题目大意
给定
n 个点的图,时刻t 在u 节点,那么t+1 时刻会在b_{a,t\bmod a_u} 节点,其中a_u 是2 的幂。数据范围:$n,\sum a_u\le 10^5,d\le 10^{18}$。
思路分析
首先肯定需要倍增,
但我们发现此时直接切换到
因此
那么查询复杂度
注意到我们的瓶颈时
那么我们不妨改变定义,直接令
那么询问时我们会用
时间复杂度
代码呈现
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=1e5+5;
const ll inf=2e18;
int n,q,a[MAXN];
vector <int> b[MAXN],f[MAXN][64];
vector <ll> d[MAXN][64];
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n;++i) {
b[i].resize(a[i]);
for(int &p:b[i]) cin>>p;
for(int k=0;k<=60;++k) d[i][k].resize(a[i]),f[i][k].resize(a[i]);
}
for(int s=1;s<MAXN;s<<=1) {
for(int u=1;u<=n;++u) if(a[u]==s) {
for(int i=0;i<s;++i) {
int v=b[u][i]; ll t=1;
while(a[v]<s&&t<inf) {
int w=f[v][60][(i+t)%a[v]];
t+=d[v][60][(i+t)%a[v]],v=w;
}
f[u][0][i]=v,d[u][0][i]=min(t,inf);
}
}
for(int k=1;k<=60;++k) for(int u=1;u<=n;++u) if(a[u]==s) {
for(int i=0;i<s;++i) {
int v=f[u][k-1][i]; ll t=d[u][k-1][i];
if(a[v]==s) {
f[u][k][i]=f[v][k-1][(i+t)%s];
d[u][k][i]=min(d[v][k-1][(i+t)%s]+t,inf);
} else f[u][k][i]=v,d[u][k][i]=t;
}
}
}
for(int u;q--;) {
ll dis,cur;
cin>>u>>cur>>dis;
while(dis) {
for(int k=60;~k;--k) if(dis>=d[u][k][cur%a[u]]) {
int v=f[u][k][cur%a[u]];
ll t=d[u][k][cur%a[u]];
if(a[v]!=a[u]) k=61;
dis-=t,cur+=t,u=v;
}
if(dis) u=b[u][cur%a[u]],--dis,++cur;
}
cout<<u<<"\n";
}
return 0;
}