暴力的建出循环mm次的飞行器图,长度n×m5e6n \times m \leq 5e6

之后考虑每个点ii处能一次跳到的位置共有1212个,即筛子数为j[1,6]j \in [1, 6]直接走到i+ji + j 处后选择不走,或者

走到i+ji + j处后继续选择走ai+ja_{i + j}步,即一步内共1212种走法:j[1,6], i+jj \in [1, 6], ~i + j i+j+ai+j~i + j + a_{i + j},考虑边数上限为n×m×126e7n \times m \times 12 \leq 6e7条,时间复杂度还算可以,所以直接从起点跑bfsbfs即可,但是注意的是不能真的把图建出来,我建图跑了一发MLE,因为每个点ii的边都是固定的1212条直接bfsbfs过程中扩展就行了。

总时间复杂度O(nm)O(nm)

const int N = 5e6 + 10, M = 1e4 + 10;

int a[N];
int dis[N];
int b[M];
int n, m;

void bfs()
{
    queue<int> que;
    que.push(1);
    dis[1] = 0;
    while(!que.empty())
    {
        int u = que.front(); que.pop();
        for(int i = 1;i <= 6;i ++)
        {
            int v = min(n * m + 1, u + i);
            if(dis[v] > dis[u] + 1)
            {
                dis[v] = dis[u] + 1;
                que.push(v);
            }
            v = min(n * m + 1, u + i + a[u + i]);
            if(dis[v] > dis[u] + 1)
            {
                dis[v] = dis[u] + 1;
                que.push(v);
            }
        }
    }
}

void solve(int Case)
{
    n = read(), m = read();
    for(int i = 1;i <= n;i ++) a[i] = read();
    for(int i = 1;i <= n;i ++) b[i] = read();
    for(int i = n + 1;i <= n * m;i ++)
        a[i] = a[i - n] + b[(i - 1) %  n + 1];

    for(int i = 1;i <= n * m + 1;i ++) dis[i] = inf;

    bfs();
    printf("%lld\n", dis[n * m + 1]);
}

signed main()
{
//    ios;
    int t = 1;// t = read();
    for(int i = 1;i <= t;i ++) solve(i);
    return 0;
}