Robot Cleaner Revisit

3 篇文章 0 订阅
2 篇文章 0 订阅

The statement of this problem shares a lot with problem A. The differences are that in this problem, the probability is introduced, and the constraint is different.

A robot cleaner is placed on the floor of a rectangle room, surrounded by walls. The floor consists of nn rows and mm columns. The rows of the floor are numbered from 11 to nn from top to bottom, and columns of the floor are numbered from 11 to mm from left to right. The cell on the intersection of the rr-th row and the cc-th column is denoted as (r,c)(r,c). The initial position of the robot is (rb,cb)(rb,cb).

In one second, the robot moves by drdr rows and dcdc columns, that is, after one second, the robot moves from the cell (r,c)(r,c) to (r+dr,c+dc)(r+dr,c+dc). Initially dr=1dr=1, dc=1dc=1. If there is a vertical wall (the left or the right walls) in the movement direction, dcdc is reflected before the movement, so the new value of dcdc is −dc−dc. And if there is a horizontal wall (the upper or lower walls), drdr is reflected before the movement, so the new value of drdr is −dr−dr.

Each second (including the moment before the robot starts moving), the robot cleans every cell lying in the same row or the same column as its position. There is only one dirty cell at (rd,cd)(rd,cd). The job of the robot is to clean that dirty cell.

After a lot of testings in problem A, the robot is now broken. It cleans the floor as described above, but at each second the cleaning operation is performed with probability p100p100 only, and not performed with probability 1−p1001−p100. The cleaning or not cleaning outcomes are independent each second.

Given the floor size nn and mm, the robot's initial position (rb,cb)(rb,cb) and the dirty cell's position (rd,cd)(rd,cd), find the expected time for the robot to do its job.

It can be shown that the answer can be expressed as an irreducible fraction xyxy, where xx and yy are integers and y≢0(mod109+7)y≢0(mod109+7). Output the integer equal to x⋅y−1mod(109+7)x⋅y−1mod(109+7). In other words, output such an integer aa that 0≤a<109+70≤a<109+7 and a⋅y≡x(mod109+7)a⋅y≡x(mod109+7).

Input

Each test contains multiple test cases. The first line contains the number of test cases tt (1≤t≤101≤t≤10). Description of the test cases follows.

A test case consists of only one line, containing nn, mm, rbrb, cbcb, rdrd, cdcd, and pp (4≤n⋅m≤1054≤n⋅m≤105, n,m≥2n,m≥2, 1≤rb,rd≤n1≤rb,rd≤n, 1≤cb,cd≤m1≤cb,cd≤m, 1≤p≤991≤p≤99) — the sizes of the room, the initial position of the robot, the position of the dirt cell and the probability of cleaning in percentage.

Output

For each test case, print a single integer — the expected time for the robot to clean the dirty cell, modulo 109+7109+7.

Example

input

Copy

6
2 2 1 1 2 1 25
3 3 1 2 2 2 25
10 10 1 1 10 10 75
10 10 10 10 1 1 75
5 5 1 3 2 2 10
97 98 3 5 41 43 50

output

Copy

3
3
15
15
332103349
99224487

Note

In the first test case, the robot has the opportunity to clean the dirty cell every second. Using the geometric distribution, we can find out that with the success rate of 25%25%, the expected number of tries to clear the dirty cell is 10.25=410.25=4. But because the first moment the robot has the opportunity to clean the cell is before the robot starts moving, the answer is 33.

Illustration for the first example. The blue arc is the robot. The red star is the target dirt cell. The purple square is the initial position of the robot. Each second the robot has an opportunity to clean a row and a column, denoted by yellow stripes.

In the second test case, the board size and the position are different, but the robot still has the opportunity to clean the dirty cell every second, and it has the same probability of cleaning. Therefore the answer is the same as in the first example.

Illustration for the second example.

The third and the fourth case are almost the same. The only difference is that the position of the dirty cell and the robot are swapped. But the movements in both cases are identical, hence the same result.

思路:期望:是某个数的 概率✖某个数。该题让我们求期望,我们当前所在的位置有两种可能:(设当前步的期望为x,下一步的期望为y)这一步就能清理,花费0秒。第二种:这一步清理不掉,走到下一步,那么下一步就要花费y+1秒。p'=1-p是无法清理的概率,那么就会新的关系:x=p' * (1+y)(这两种可能是每一步都在能够清理垃圾的行或列上)。假设当前步不在垃圾的行列上:那么就一定会花费1+y秒走到下一步,就有x=1+y。举一个例子:在2×3的格子中,机器在(1,1),垃圾在(2,3)即可得到一下关系:

 

  这样我们只需要用u每次记录加法常量,v记录次方常量。(这题和更新一样,知道最后一步,才能将前面的求出,我们求公式时也是倒着代的,所以这题我们倒着找点)。方向是否更新看下一步(位置):这个题还有一个坑是在:我们不能说它在边界了就让它方向改变,如果是走到了边界可以让它改变方向,但是如果出生点在边界并且方向还是对的,你让它在边界改变,这样就会走出边界,得让它判断下一步是否在边界,走的下一步在边界才能改变,与BFS的走路判断边界一样,都是让下一步位置来判断,判断下一步的位置判断是否改变(BFS是下一步出边界不改变而这个题是下一步出界改变)

 这个题的每次循环(移动)都是周期变化,下面只需要找到一个周期走了几步就可以了。行的周期变化是2*n-2,列的周期变化是2*m-2.

那么该机器人的循环周期就是:4*((n-1)*(m-1)) / (__gcd(n-1,m-1)*2).

下面引入mint除余方法:mint和int的使用方法几乎一样,mint会自动的除余,也不需要判断正负,余数一定是正数。不一样的地方在于:使用cin与cout时,需要加上 .x,即cout<<p.x<<endl;。printf与scanf与int一样输入%d即可。

mint模板:

using ll = long long;
 
#define defop(type, op) \
    inline friend type operator op (type u, const type& v) { return u op ##= v; } \
    type& operator op##=(const type& o)
template<int mod>
struct modint {
    int x;
    // note that there is no correction, simply for speed
    modint(int xx = 0): x(xx) {}
    modint(ll xx): x(int(xx % mod)) {}
    defop(modint, +) {
        if ((x += o.x) >= mod) x -= mod;
        return *this;
    }
    defop(modint, -) {
        if ((x -= o.x) < 0) x += mod;
        return *this;
    }
    defop(modint, * ) { return *this = modint(1ll * x * o.x); }
    modint pow(ll exp) const {
        modint ans = 1, base = *this;
        for (; exp > 0; exp >>= 1, base *= base)
            if (exp & 1) ans *= base;
        return ans;
    }
    defop(modint, /) { return *this *= o.pow(mod - 2); }
};
using mint = modint<(int)1e9 + 7>;

完整代码:

#include <bits/stdc++.h>
 
using namespace std;
 
using ll = long long;
 
// I swear that I type this everytime, so this is not count as template :))
#define defop(type, op) \
    inline friend type operator op (type u, const type& v) { return u op ##= v; } \
    type& operator op##=(const type& o)
template<int mod>
struct modint {
    int x;
    // note that there is no correction, simply for speed
    modint(int xx = 0): x(xx) {}
    modint(ll xx): x(int(xx % mod)) {}
    defop(modint, +) {
        if ((x += o.x) >= mod) x -= mod;
        return *this;
    }
    defop(modint, -) {
        if ((x -= o.x) < 0) x += mod;
        return *this;
    }
    defop(modint, * ) { return *this = modint(1ll * x * o.x); }
    modint pow(ll exp) const {
        modint ans = 1, base = *this;
        for (; exp > 0; exp >>= 1, base *= base)
            if (exp & 1) ans *= base;
        return ans;
    }
    defop(modint, /) { return *this *= o.pow(mod - 2); }
};
using mint = modint<(int)1e9 + 7>;


int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m,rb,cb,rd,cd;
        mint p;
        cin>>n>>m>>rb>>cb>>rd>>cd>>p.x;
        p=1-p/100;
        int dr=-1,dc=-1;
        mint u=0,v=1;
        for(int i=0;i<2*(n-1)*(m-1)/__gcd(n-1,m-1);i++)
        {
            if(!(rb+dr>=1&&rb+dr<=n))dr*=-1;
            if(!(cb+dc>=1&&cb+dc<=m))dc*=-1;
            rb+=dr;
            cb+=dc;
            u+=1;
            if(rb==rd||cb==cd)
            {
                u*=p;
                v*=p;
            }
        }
        cout<<(u/(1-v)).x<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值