The n 0, m 1 is a circumferentially arranged adjacent and all the numbers on the same circle is arranged in a right segment of the product of the composition defined segment length, asking broken chain ring to a sum of weights of all the programs and, \ (n-, m \ Leq 5000 \) .
solution
Because of problems related to the interval division, do not direct counting of the sequence considered, we may assume \ (F [i] [j] \) for the first i elements (identical) divided into sections and the weight j, clearly
\[f[i][j]=\sum_{k=0}^{i-1}f[k][j-1](i-k)\]
This equation is \ (O (n-^. 3) \) , then consider optimization, two methods
Act One:
\[f[i][j]=i\sum_{k=0}^{i-1}f[k][j-1]-\sum_{k=0}^{i-1}kf[k][j-1]\]
So we just maintenance \ (f [k] [j -1] \) and \ (kf [k] [j -1] \) prefix and can be, for optimization of expression, usually to separate unrelated item, or one of the individual to consider the number of occurrences.
Act II:
\[f[i][j]=\sum_{k=0}^{i-1}f[k][j-1](i-k)=\]
\[\sum_{k=0}^{i-1}f[k][j-1](i-k-1)+\sum_{k=0}^{i-1}f[k][j-1]=\]
\[f[i-1][j]+f[i-1][j-1]+\sum_{k=0}^{i-1}f[k][j-1]\]
So long as we maintain \ (f [k] [j ] \) on the k prefix and I can, personally prefer Act II.
Obviously segment 0 and segment number 1 is the same, it is a property 01 sequence, so enumerator segments for \ (\ sum_ {i = 1 } ^ {min (n, m)} f [n] [i ] \ Times F [m] [I] \) , the actual meaning that is all in weight value of 0 at the beginning of the 0 ring of segments corresponding to and, while the chain at an arbitrary beginning, according to other explanations, readily know multiplied by a coefficient \ ((n-m +) / I \) , the coefficient I can not give a simple proof.
Reference Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define ll long long
#define Size 5050
#define yyb 1000000007
using namespace std;
int dp[Size][Size],s[Size],iv[Size];
int main(){
int n,m;iv[1]=1;
for(int i(2);i<=5000;++i)iv[i]=-(ll)yyb/i*iv[yyb%i]%yyb;
for(int i(1);i<=5000;++i)dp[i][1]=i;
for(int i,j(2);j<=5000;++j){
for(i=1;i<j;++i)s[i]=s[i-1]+dp[i][j-1];
for(i=j;i<=5000;++i)
dp[i][j]=(dp[i-1][j]+s[i-1])%yyb,
s[i]=(s[i-1]+dp[i][j-1])%yyb;
}
while(scanf("%d%d",&n,&m)!=EOF){
int ans(0);
for(int i(1);i<=min(n,m);++i)
ans=(ans+(ll)dp[n][i]*dp[m][i]%yyb*(n+m)%yyb*iv[i])%yyb;
printf("%d\n",(ans+yyb)%yyb);
}
return 0;
}