Description
Imagine that you are in a building that has exactly n floors. You can move between the floors in a lift. Let’s number the floors from bottom to top with integers from 1 to n. Now you’re on the floor number a. You are very bored, so you want to take the lift. Floor number b has a secret lab, the entry is forbidden. However, you already are in the mood and decide to make k consecutive trips in the lift.
Let us suppose that at the moment you are on the floor number x (initially, you were on floor a). For another trip between floors you choose some floor with number y ( y ≠ x) and the lift travels to this floor. As you cannot visit floor b with the secret lab, you decided that the distance from the current floor x to the chosen y must be strictly less than the distance from the current floor x to floor b with the secret lab. Formally, it means that the following inequation must fulfill: |x - y| < |x - b|. After the lift successfully transports you to floor y, you write down number y in your notepad.
Your task is to find the number of distinct number sequences that you could have written in the notebook as the result of k trips in the lift. As the sought number of trips can be rather large, find the remainder after dividing the number by 1000000007 (109 + 7).
Input
The first line of the input contains four space-separated integers
n
,
a
,
b
,
k
(
2
≤
n
≤
5000
,
1
≤
k
≤
5000
,
1
≤
a
,
b
≤
n
,
a
≠
b
)
n, a, b, k (2 ≤ n ≤ 5000, 1 ≤ k ≤ 5000, 1 ≤ a, b ≤ n, a ≠ b)
n,a,b,k(2 ≤ n ≤ 5000,1 ≤ k ≤ 5000,1 ≤ a, b ≤ n,a = b).
Output
Print a single integer — the remainder after dividing the sought number of sequences by 1000000007
(
1
0
9
+
7
)
(10^9 + 7)
(109 + 7).
Examples
Input
5 2 4 1
Output
2
Input
5 2 4 2
Output
2
Input
5 3 4 1
Output
0
Solution
如果暴力去统计答案,需要
O
(
n
3
)
O(n^3)
O(n3),考虑优化
容易发现上一步某一楼层的贡献会转移到当前步某一个区间内所有的楼层,故可以用差分数组来优化区间修改
再滚动差分数组优化空间
Code
int n,a,b,k;
int d[2][maxn];
inline int MAX(int a,int b){if(a > b) return a;return b;}
inline int MIN(int a,int b){if(a < b) return a;return b;}
inline void init(int op){for(re int i = 1;i <= n;++i) d[op][i] = 0;}
void modify(int L,int R,int k,int op){
d[op][L] = (1ll * d[op][L] + k + mod) % mod;
d[op][R+1] = (1ll * d[op][R+1] - k + mod) % mod;
}
int main(){
scanf("%d%d%d%d",&n,&a,&b,&k);
modify(a,a,1,0);
int op = 1;
while(k--){
init(op);
int val = 0;
for(int x = 1;x <= n;++x){
val = (1ll * val + d[op^1][x]) % mod;
if(x == b) continue;
if(val == 0) continue;
if(x < b) modify(MAX(2*x-b+1,1),b-1,val,op);
if(x > b) modify(b+1,MIN(2*x-b-1,n),val,op);
modify(x,x,-val,op);
}
op ^= 1;
}
op ^= 1;
int res = 0, tmp = 0;
for(re int i = 1;i <= n;i++){
tmp = (1ll * tmp + d[op][i]) % mod;
if(i != b) res = (1ll * res + tmp) % mod;
}
printf("%d\n", res % mod);
return 0;
}