数论五之容斥——硬币购物,Gerald and Giant Chess,幸运数字,Sky Full of Stars,已经没有什么好害怕的了

容斥的神

  • [HAOI2008]硬币购物
    • problem
    • solution
    • code
  • CF559C Gerald and Giant Chess
    • problem
    • solution
    • code
  • [SCOI2010]幸运数字
    • problem
    • solution
    • code
  • CF997C Sky Full of Stars
    • problem
    • solution
    • code
  • 已经没有什么好害怕的了
    • problem
    • solution
    • code
  • [JLOI2015]骗我呢
    • problem
    • solution
    • code

容斥要么是dp预处理,要么是组合数推导(纯数学式子化简),要么是dfs搜索剪枝

在这里插入图片描述

[HAOI2008]硬币购物

problem

solution

先不管ddd的限制,预处理每一个sss的方案数

然后容斥−-至少一个超出ddd限制+++至少两个超出ddd限制−-至少三个超出ddd限制+++至少四个超出ddd限制

我们可以强制超出ddd限制,以超出d1d_1d1为例

强制使用d1+1d_1+1d1+1c1c_1c1,那么剩下s−(d1+1)c1s-(d_1+1)c_1s(d1+1)c1​​的空间随便用即预处理的dps−(d1+1)c1dp_{s-(d_1+1)c_1}dps(d1+1)c1

code

#include <cstdio>
#define maxn 100005
#define int long long
int tot, c1, c2, c3, c4, d1, d2, d3, d4, s;
int dp[maxn];void init( int c ) {for( int i = c;i <= 1e5;i ++ )dp[i] += dp[i - c];
}signed main() {scanf( "%lld %lld %lld %lld %lld", &c1, &c2, &c3, &c4, &tot );dp[0] = 1;init( c1 ), init( c2 ), init( c3 ), init( c4 );while( tot -- ) {scanf( "%lld %lld %lld %lld %lld", &d1, &d2, &d3, &d4, &s );int ans = dp[s];if( c1 * ( d1 + 1 ) <= s ) ans -= dp[s - c1 * ( d1 + 1 )];if( c2 * ( d2 + 1 ) <= s ) ans -= dp[s - c2 * ( d2 + 1 )];if( c3 * ( d3 + 1 ) <= s ) ans -= dp[s - c3 * ( d3 + 1 )];if( c4 * ( d4 + 1 ) <= s ) ans -= dp[s - c4 * ( d4 + 1 )];if( c1 * ( d1 + 1 ) + c2 * ( d2 + 1 ) <= s ) ans += dp[s - c1 * ( d1 + 1 ) - c2 * ( d2 + 1 )];if( c1 * ( d1 + 1 ) + c3 * ( d3 + 1 ) <= s ) ans += dp[s - c1 * ( d1 + 1 ) - c3 * ( d3 + 1 )];if( c1 * ( d1 + 1 ) + c4 * ( d4 + 1 ) <= s ) ans += dp[s - c1 * ( d1 + 1 ) - c4 * ( d4 + 1 )];if( c2 * ( d2 + 1 ) + c3 * ( d3 + 1 ) <= s ) ans += dp[s - c2 * ( d2 + 1 ) - c3 * ( d3 + 1 )];if( c2 * ( d2 + 1 ) + c4 * ( d4 + 1 ) <= s ) ans += dp[s - c2 * ( d2 + 1 ) - c4 * ( d4 + 1 )];if( c3 * ( d3 + 1 ) + c4 * ( d4 + 1 ) <= s ) ans += dp[s - c3 * ( d3 + 1 ) - c4 * ( d4 + 1 )];if( c1 * ( d1 + 1 ) + c2 * ( d2 + 1 ) + c3 * ( d3 + 1 ) <= s ) ans -= dp[s - c1 * ( d1 + 1 ) - c2 * ( d2 + 1 ) - c3 * ( d3 + 1 )];if( c1 * ( d1 + 1 ) + c2 * ( d2 + 1 ) + c4 * ( d4 + 1 ) <= s ) ans -= dp[s - c1 * ( d1 + 1 ) - c2 * ( d2 + 1 ) - c4 * ( d4 + 1 )];if( c1 * ( d1 + 1 ) + c3 * ( d3 + 1 ) + c4 * ( d4 + 1 ) <= s ) ans -= dp[s - c1 * ( d1 + 1 ) - c3 * ( d3 + 1 ) - c4 * ( d4 + 1 )];if( c2 * ( d2 + 1 ) + c3 * ( d3 + 1 ) + c4 * ( d4 + 1 ) <= s ) ans -= dp[s - c2 * ( d2 + 1 ) - c3 * ( d3 + 1 ) - c4 * ( d4 + 1 )];if( c1 * ( d1 + 1 ) + c2 * ( d2 + 1 ) + c3 * ( d3 + 1 ) + c4 * ( d4 + 1 ) <= s ) ans += dp[s - c1 * ( d1 + 1 ) - c2 * ( d2 + 1 ) - c3 * ( d3 + 1 ) - c4 * ( d4 + 1 )];printf( "%lld\n", ans );}return 0;
}

CF559C Gerald and Giant Chess

problem

solution

到某个点(i,j)(i,j)(i,j)的方案数为(i+j−2i−1)\binom{i+j-2}{i-1}(i1i+j2),将终点也看做一个黑格子

dpidp_idpi表示走到只经过第iii个黑格子的方案数,枚举可能经过的黑格子j(xj≤xi,yj≤yi)j(x_j\le x_i,y_j\le y_i)j(xjxi,yjyi)

容斥,dpi=dpi−∑j,xj≤xi,yj≤yidpj∗(xi−xj+yi−yjxi−xj)dp_{i}=dp_i-\sum_{j,x_j\le x_i,y_j\le y_i}dp_j*\binom{x_i-x_j+y_i-y_j}{x_i-x_j}dpi=dpij,xjxi,yjyidpj(xixjxixj+yiyj)

code

#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
#define mod 1000000007
#define maxn 200000
struct node {int x, y;node(){}node( int X, int Y ) { x = X, y = Y; }
}pos[maxn];
int fac[maxn + 5], inv[maxn + 5], dp[maxn];
int h, w, n;bool cmp( node MS, node IS ) {return MS.x == IS.x ? MS.y < IS.y : MS.x < IS.x;
}int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void init() {fac[0] = inv[0] = 1;for( int i = 1;i <= maxn;i ++ )fac[i] = fac[i - 1] * i % mod;inv[maxn] = qkpow( fac[maxn], mod - 2 );for( int i = maxn - 1;i;i -- )	inv[i] = inv[i + 1] * ( i + 1 ) % mod;
}int C( int n, int m ) {return fac[n] * inv[m] % mod * inv[n - m] % mod;
}signed main() {init();scanf( "%lld %lld %lld", &h, &w, &n );for( int i = 1;i <= n;i ++ )scanf( "%lld %lld", &pos[i].x, &pos[i].y );++ n; pos[n] = node( h, w );sort( pos + 1, pos + n + 1, cmp );for( int i = 1;i <= n;i ++ ) {int x = pos[i].x, y = pos[i].y;dp[i] = C( x + y - 2, x - 1 );for( int j = 1;j < i;j ++ )if( pos[j].x <= x && pos[j].y <= y )dp[i] = ( dp[i] - dp[j] * C( x - pos[j].x + y - pos[j].y, x - pos[j].x ) % mod + mod ) % mod;}printf( "%lld\n", dp[n] );return 0;
}

[SCOI2010]幸运数字

problem

solution

区间[l,r][l,r][l,r]iii的倍数个数为⌊ri⌋−⌈li⌉+1\lfloor\frac{r}{i}\rfloor-\lceil\frac{l}{i}\rceil+1iril+1

容斥,至少选一个幸运数字−-​至少选两个幸运数字+++​至少选三个幸运数字...∑i=1n(−1)i−1...\sum_{i=1}^n(-1)^{i-1}...i=1n(1)i1

如果直接暴搜1e101e101e10以内所有的幸运数字(204620462046个)的倍数是不可取的

需要搜索剪枝

  • 如果幸运数字iii是幸运数字jjj的倍数,那么iii就可以不用考虑了
  • 如果现在的幸运数字的lcmlcmlcm已经超过上限,也果断退出
  • 将幸运数字从大到小排序搜索,更容易爆出设定边界,减少前期不必要的分叉搜索

code

#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
#define maxn 3000
ll ans, L, R;
int tot, cnt;
ll id[maxn], num[maxn];
bool vis[maxn];void dfs1( int lim, int len, ll now, ll dig ) {if( len > lim ) {id[++ tot] = now;return;}dfs1( lim, len + 1, now + dig * 6, dig * 10 );dfs1( lim, len + 1, now + dig * 8, dig * 10 );
}void init() {for( int i = 1;i <= tot;i ++ ) {if( ! vis[i] ) num[++ cnt] = id[i];for( int j = i + 1;j <= tot;j ++ )if( id[j] % id[i] == 0 ) vis[j] = 1;}
} ll gcd( ll x, ll y ) {if( ! y ) return x;else return gcd( y, x % y );
}ll calc( ll x ) {ll l = L / x + ( L % x != 0 ), r = R / x;return r - l + 1;
}void dfs2( int x, int used, ll lcm ) {if( x > cnt ) {if( ! used ) return;ans += ( used & 1 ? 1 : -1 ) * calc( lcm );return;}dfs2( x + 1, used, lcm );ll t = lcm / gcd( lcm, num[x] );if( 1.0 * t * num[x] <= R )dfs2( x + 1, used + 1, t * num[x] );
}bool cmp( ll x, ll y ) { return x > y; }int main() {scanf( "%lld %lld", &L, &R );for( int i = 1;i <= 10;i ++ ) dfs1( i, 1, 0, 1 );init();sort( num + 1, num + cnt + 1, cmp );dfs2( 1, 0, 1 );printf( "%lld\n", ans );return 0;
}

CF997C Sky Full of Stars

problem

solution

容斥:∑i=0n∑j=0n[i+j>0](−1)i+j+1CniCnjdpi,j\sum_{i=0}^n\sum_{j=0}^n[i+j>0](-1)^{i+j+1}C_n^iC_n^jdp_{i,j}i=0nj=0n[i+j>0](1)i+j+1CniCnjdpi,j

dpi,j:idp_{i,j}:idpi,j:ijjj​列颜色相同的方案数

考虑对dpi,jdp_{i,j}dpi,j进行求解,分类讨论

  • 只有行/列颜色相同,i=0/j=0i=0/j=0i=0/j=0(以行为例)

    iii行颜色相同,每行颜色有333种选择,剩下的n∗(n−i)n*(n-i)n(ni)格子是自由选择

    3i×3n∗(n−i)3^i\times 3^{n*(n-i)}3i×3n(ni)

  • iiijjj列颜色相同

    行与列有交,整个整体只有333种选择,剩下的(n−i)(n−j)(n-i)(n-j)(ni)(nj)格子是自由选择

    3×3(n−i)(n−j)3\times 3^{(n-i)(n-j)}3×3(ni)(nj)

dpi,j={3i×3n∗(n−i)j=03j×3n∗(n−j)i=03×3(n−i)(n−j)i≠0,j≠0dp_{i,j}= \begin{cases} 3^i\times 3^{n*(n-i)}&&j=0\\ 3^j\times 3^{n*(n-j)}&&i=0\\ 3\times 3^{(n-i)(n-j)}&&i≠0,j≠0 \end{cases} dpi,j=3i×3n(ni)3j×3n(nj)3×3(ni)(nj)j=0i=0i=0,j=0

i=0/j=0i=0/j=0i=0/j=0​的dpdpdp​​式子比较特殊,考虑单独计算
∑i=1n(−1)i+1Cnidpi,0+∑j=1n(−1)j+1Cnjdpj,0=2∑i=1n(−1)i+1Cni3i⋅3n(n−i)\sum_{i=1}^n(-1)^{i+1}C_n^idp_{i,0}+\sum_{j=1}^n(-1)^{j+1}C_n^jdp_{j,0}\\ =2\sum_{i=1}^n(-1)^{i+1}C_n^i3^i·3^{n(n-i)} i=1n(1)i+1Cnidpi,0+j=1n(1)j+1Cnjdpj,0=2i=1n(1)i+1Cni3i3n(ni)
然后计算剩下的普通式子
∑i=1n∑j=1n(−1)i+j+1CniCnj⋅3⋅3(n−i)(n−j)=∑i=1n∑j=1n(−1)i(−1)j(−1)CniCnj3n2+13−in3−jn3ij=(−1)3n2+1∑i=1n(−1)iCni3−in∑j=1n(−1)jCnj3−jn3ij=(−1)3n2+1∑i=1n(−1)iCni3−in∑j=1nCnj(−1)j3(−n+i)j=(−1)3n2+1∑i=1n(−1)iCni3−in∑j=1nCnj(−3−n+i)j\sum_{i=1}^n\sum_{j=1}^n(-1)^{i+j+1}C_n^iC_n^j·3·3^{(n-i)(n-j)}\\ =\sum_{i=1}^n\sum_{j=1}^n(-1)^i(-1)^j(-1)C_n^iC_n^j3^{n^2+1}3^{-in}3^{-jn}3^{ij}\\ =(-1)3^{n^2+1}\sum_{i=1}^n(-1)^iC_n^i3^{-in}\sum_{j=1}^n(-1)^jC_n^j3^{-jn}3^{ij}\\ =(-1)3^{n^2+1}\sum_{i=1}^n(-1)^iC_n^i3^{-in}\sum_{j=1}^nC_n^j(-1)^j3^{{(-n+i)}^j}\\ =(-1)3^{n^2+1}\sum_{i=1}^n(-1)^iC_n^i3^{-in}\sum_{j=1}^nC_n^j(-3^{-n+i})^j i=1nj=1n(1)i+j+1CniCnj33(ni)(nj)=i=1nj=1n(1)i(1)j(1)CniCnj3n2+13in3jn3ij=(1)3n2+1i=1n(1)iCni3inj=1n(1)jCnj3jn3ij=(1)3n2+1i=1n(1)iCni3inj=1nCnj(1)j3(n+i)j=(1)3n2+1i=1n(1)iCni3inj=1nCnj(3n+i)j
有二项式定理:(a+b)n=∑i=0nCniaibn−i(a+b)^n=\sum_{i=0}^nC_n^ia^ib^{n-i}(a+b)n=i=0nCniaibni

a=1,b=−3−n+ia=1,b=-3^{-n+i}a=1,b=3n+i​​带入
(a+b)n=(1−3−n+i)n=∑j=0nCnj(−3−n+i)j1n−j(a+b)^n=\Big(1-3^{-n+i}\Big)^n=\sum_{j=0}^nC_n^j(-3^{-n+i})^j1^{n-j} (a+b)n=(13n+i)n=j=0nCnj(3n+i)j1nj
二项式定理是从000的,所以要减去j=0j=0j=0的贡献
(−1)3n2+1∑i=1n(−1)iCni3−in∑j=1nCnj(−3−n+i)j=(−1)3n2+1∑i=1n((−1)iCni3−in((1−3−n+i)n−1))(-1)3^{n^2+1}\sum_{i=1}^n(-1)^iC_n^i3^{-in}\sum_{j=1}^nC_n^j(-3^{-n+i})^j\\ =(-1)3^{n^2+1}\sum_{i=1}^n\bigg((-1)^iC_{n}^i3^{-in}\Big((1-3^{-n+i})^n-1\Big)\bigg) (1)3n2+1i=1n(1)iCni3inj=1nCnj(3n+i)j=(1)3n2+1i=1n((1)iCni3in((13n+i)n1))
两种情况综上,答案为
2∑i=1n(−1)i+1Cni3i3n(n−i)+(−1)3n2+1∑i=1n(−1)iCni3−in((1−3−n+i)n−1)2\sum_{i=1}^n(-1)^{i+1}C_n^i3^i3^{n(n-i)}+(-1)3^{n^2+1}\sum_{i=1}^n(-1)^iC_{n}^i3^{-in}\Big((1-3^{-n+i})^n-1\Big) 2i=1n(1)i+1Cni3i3n(ni)+(1)3n2+1i=1n(1)iCni3in((13n+i)n1)

code

#include <cstdio>
#define int long long
#define mod 998244353
#define maxn 1000005
int n;
int fac[maxn], inv[maxn];int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void init() {fac[0] = inv[0] = 1;for( int i = 1;i <= n;i ++ )fac[i] = fac[i - 1] * i % mod;inv[n] = qkpow( fac[n], mod - 2 );for( int i = n - 1;i;i -- )inv[i] = inv[i + 1] * ( i + 1 ) % mod;
}int C( int n, int m ) {return fac[n] * inv[m] % mod * inv[n - m] % mod;
}signed main() {scanf( "%lld", &n );init();int ans = 0, ret = 0;for( int i = 1;i <= n;i ++ )if( i & 1 ) {ans = ( ans - C( n, i ) * qkpow( qkpow( 3, i * n ), mod - 2 ) % mod * ( qkpow( 1 - qkpow( qkpow( 3,  n - i ), mod - 2 ), n ) - 1 ) % mod ) % mod;ret = ( ret + C( n, i ) * qkpow( 3, n * ( n - i ) + i ) ) % mod;}else {ans = ( ans + C( n, i ) * qkpow( qkpow( 3, i * n ), mod - 2 ) % mod * ( qkpow( 1 - qkpow( qkpow( 3,  n - i ), mod - 2 ), n ) - 1 ) % mod ) % mod;ret = ( ret - C( n, i ) * qkpow( 3, n * ( n - i ) + i ) ) % mod;}ans = ans * -1 * qkpow( 3, n * n + 1 ) % mod;ret = ret * 2 % mod;printf( "%lld\n", ( ans + ret + mod + mod ) % mod );return 0;
}

已经没有什么好害怕的了

problem

solution

保证不会有重复的数字暗示了如果有k组糖果比药片能量大那么剩下的n-k组一定都是药片比糖果大

若恰好糖果比药片能量大的组数 比 药片比糖果能量大的组数多K组

反解出k=n+K2,kk=\frac{n+K}{2},kk=2n+K,k​​表示糖果比药片能量大的组数

先将糖果和药片分别按能量大小排序,设fi,jf_{i,j}fi,j​表示前iii​颗糖果中有jjj​组满足糖果能量大于药片

fi,j=fi−1,j+(cnti−(j−1))fi−1,j−1;;cnti:f_{i,j}=f_{i-1,j}+\Big(cnt_i-(j-1)\Big)f_{i-1,j-1};;cnt_i:fi,j=fi1,j+(cnti(j1))fi1,j1;;cnti:​ 药片能量小于糖果iii​​的药片个数

gi=(n−i)!fn,ig_i=(n-i)!f_{n,i}gi=(ni)!fn,i,表示把剩下的n−in-ini个随意分配,得到糖果大于药片的组数至少为iii的方案数

果断标准广义容斥

  • fi:f_i:fi: 至多选,gig_igi恰好选

    fn=∑i=0n(ni)gi⇒gn=∑i=0n(−1)n−i(ni)fif_n=\sum_{i=0}^n\binom{n}{i}g_i\Rightarrow g_n=\sum_{i=0}^n(-1)^{n-i}\binom{n}{i}f_ifn=i=0n(in)gign=i=0n(1)ni(in)fi

  • fi:f_i:fi: 至少选,gig_igi恰好选

    fk=∑i=kn(ik)gi⇒gk=∑i=kn(−1)i−k(ik)fif_k=\sum_{i=k}^n\binom{i}{k}g_i\Rightarrow g_k=\sum_{i=k}^n(-1)^{i-k}\binom{i}{k}f_ifk=i=kn(ki)gigk=i=kn(1)ik(ki)fi

一般fif_ifi是非常好求的,反演求恰好的gig_igi

ans=∑i=kn(−1)i−k(ik)gians=\sum_{i=k}^n(-1)^{i-k}\binom{i}{k}g_ians=i=kn(1)ik(ki)gi

code

#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 2005
#define int long long
#define mod 1000000009
int n, k;
int candy[maxn], medicine[maxn], fac[maxn], inv[maxn];
int f[maxn][maxn];int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void init() {fac[0] = inv[0] = 1;for( int i = 1;i <= n;i ++ )fac[i] = fac[i - 1] * i % mod;inv[n] = qkpow( fac[n], mod - 2 );for( int i = n - 1;i;i -- )inv[i] = inv[i + 1] * ( i + 1 ) % mod;
}int C( int n, int m ) {return fac[n] * inv[m] % mod * inv[n - m] % mod;
}signed main() {scanf( "%lld %lld", &n, &k );if( ( n + k ) & 1 ) return ! printf( "0\n" );k = ( n + k ) >> 1; init();for( int i = 1;i <= n;i ++ )scanf( "%lld", &candy[i] );for( int i = 1;i <= n;i ++ )scanf( "%lld", &medicine[i] );sort( candy + 1, candy + n + 1 );sort( medicine + 1, medicine + n + 1 );int cnt = 0;f[0][0] = 1; for( int i = 1;i <= n;i ++ ) {f[i][0] = 1;while( cnt < n && medicine[cnt + 1] < candy[i] ) cnt ++;for( int j = 1;j <= i;j ++ )f[i][j] = ( f[i - 1][j] + ( cnt - j + 1 ) * f[i - 1][j - 1] ) % mod;}int ans = 0;for( int i = k;i <= n;i ++ )if( ( i - k ) & 1 )ans = ( ans - C( i, k ) * fac[n - i] % mod * f[n][i] ) % mod;elseans = ( ans + C( i, k ) * fac[n - i] % mod * f[n][i] ) % mod;printf( "%lld\n", ( ans + mod ) % mod );return 0;
}

在这里插入图片描述

[JLOI2015]骗我呢

problem

solution

性质:每行必须严格递增,且每行mmm个 ,取值范围被限制于[0,m][0,m][0,m];所以一行有且只有一个比前面的大222​,剩下的一定都是比前面的大恰好111

dpi,j:dp_{i,j}:dpi,j:iii行没有出现的数为jjj的方案数

dpi,j=∑k=1j+1dpi−1,kdp_{i,j}=\sum_{k=1}^{j+1}dp_{i-1,k}dpi,j=k=1j+1dpi1,k

若第iii行没有出现jjj,那么(j,n](j,n](j,n]n−jn-jnj个数都是出现的,除去最大值放在最后一个,也至少需要n−j−1n-j-1nj1个数使得能够满足矩阵要求,所以上一行的上限就是j+1j+1j+1不出现,(j+1,n](j+1,n](j+1,n]n−j−1n-j-1nj1

dpi,j=∑k=1j+1dpi−1,k;dpi,j−1=∑k=1jdpi−1,kdp_{i,j}=\sum_{k=1}^{j+1}dp_{i-1,k};dp_{i,j-1}=\sum_{k=1}^jdp_{i-1,k}dpi,j=k=1j+1dpi1,k;dpi,j1=k=1jdpi1,k

⇒dpi,j=dpi−1,j+1+dpi,j−1[j>0]\Rightarrow dp_{i,j}=dp_{i-1,j+1}+dp_{i,j-1}\qquad[j>0]dpi,j=dpi1,j+1+dpi,j1[j>0]

转化成二维图形上的关联↓

在这里插入图片描述

稍微变换一下(红线是形式上的辅助理解)

在这里插入图片描述

对称一下

在这里插入图片描述

这完全就是卡特兰数的几何意义解法,非常类似,我们套路的知道可以跟组合数扯上关系

从原点出发,不经过直线l1,l2l_1,l_2l1,l2,最后到达(n+m+1,n)(n+m+1,n)(n+m+1,n)的路径数

l1:y=x+1;l2:y=x−(m+2)l_1:y=x+1;l_2:y=x-(m+2)l1:y=x+1;l2:y=x(m+2)

每一条路径都对应着从原点到翻折点的路径数

在这里插入图片描述

每条路径要么先碰l1l_1l1要么先碰l2l_2l2,所以用所有方案数减去先碰l1l_1l1方案数减去先碰l2l_2l2方案数

减去以l1l_1l1开头的方案数,需要减去以l1,l1l2l_1,l_1l_2l1,l1l2结尾的方案加上l2l1,l2l1l2l_2l_1,l_2l_1l_2l2l1,l2l1l2结尾的.........

实现过程:将(x,y)(x,y)(x,y)沿直线l1l_1l1​翻折,减去答案,将翻折点沿l2l_2l2翻折,加上答案.........

l2l_2l2开头的同理,(x,y)→(y−1,x+1)/(y+m+2,x−m−2)(x,y)\rightarrow(y-1,x+1)/(y+m+2,x-m-2)(x,y)(y1,x+1)/(y+m+2,xm2)

code

#include <cstdio>
#include <iostream>
using namespace std;
#define mod 1000000007
#define int long long
#define maxn 5000000
int fac[maxn + 5], inv[maxn + 5];
int n, m;int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}void init() {fac[0] = inv[0] = 1;for( int i = 1;i <= maxn;i ++ )fac[i] = fac[i - 1] * i % mod;inv[maxn] = qkpow( fac[maxn], mod - 2 );for( int i = maxn - 1;i;i -- )inv[i] = inv[i + 1] * ( i + 1 ) % mod;
}int C( int x, int y ) {if( x < 0 || y < 0 ) return 0;else return fac[x + y] * inv[x] % mod * inv[y] % mod;
}void work1( int &x, int &y ) {swap( x, y ), x --, y ++;
}void work2( int &x, int &y ) {swap( x, y ), x += ( m + 2 ), y -= ( m + 2 );
}signed main() {init();scanf( "%lld %lld", &n, &m );int x = n + m + 1, y = n, ans = C( x, y );while( x >= 0 && y >= 0 ) {work1( x, y );ans = ( ans - C( x, y ) ) % mod;work2( x, y );ans = ( ans + C( x, y ) ) % mod;}x = n + m + 1, y = n;while( x >= 0 && y >= 0 ) {work2( x, y );ans = ( ans - C( x, y ) ) % mod;work1( x, y );ans = ( ans + C( x, y ) ) % mod;}printf( "%lld\n", ( ans + mod ) % mod );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317298.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P4769-[NOI2018]冒泡排序【组合数学,树状数组】

正题 题目链接:https://www.luogu.com.cn/problem/P4769 题目大意 有一个冒泡排序的算法 输入&#xff1a;一个长度为 n 的排列 p[1...n] 输出&#xff1a;p 排序后的结果。 for i 1 to n dofor j 1 to n - 1 doif(p[j] > p[j 1])交换 p[j] 与 p[j 1] 的值然后给出一…

NET Core微服务之路:基于Ocelot的API网关Relay实现--RPC篇

前言我们都知道&#xff0c;API网关是工作在应用层上网关程序&#xff0c;为何要这样设计呢&#xff0c;而不是将网关程序直接工作在传输层、或者网络层等等更底层的环境呢&#xff1f;让我们先来简单的了解一下TCP/IP的五层模型。&#xff08;图片出自http://www.cnblogs.com/…

模板:长链剖分

所谓长链剖分&#xff0c;就是对长链进行剖分 &#xff08;逃&#xff09; 前言 很优雅的算法 利用对指针进行魔法操作将 n2n^2n2 的 dp 优化成线性 线性啊&#xff01;&#xff01;&#xff01; 解析 CF1009F Dominant Indices 给定一棵以 111 为根&#xff0c;nnn 个节点…

acwing 327. 玉米田

327. 玉米田 题意&#xff1a; m * n的土地&#xff0c;有的土地不育&#xff0c;有的可以种植&#xff0c;要求相邻的土地不能同时种植玉米&#xff0c;问有多少种种植方式 题解&#xff1a; 状压dp&#xff0c;先存每一行可能的状态&#xff0c;然后状态转移&#xff0c;…

Windows 10《描图》应用现已开源

点击上方蓝字关注“汪宇杰博客”《描图》是我最早的Windows 10应用&#xff0c;发布至今已3年多&#xff0c;积累了全球数百万用户&#xff0c;广受好评。现已开源。这款应用为不少小朋友带去了欢乐&#xff0c;体验绘画的乐趣&#xff0c;也帮助过专业用户复刻数百幅古代绘画。…

数论六之计算几何干货——计算几何模板解释全集 及 模板检验训练场

文章目录点和向量及运算直线和线段求解点到直线的距离/点在直线上求解点到线段的距离/点在线段上求解两条线段是否相交求解两直线的交点多边形求解多边形面积求解多边形重心求解判断定点与多边形的位置关系凸包graham扫描法graham扫描法加强版圆求解圆与直线的交点求解圆与圆的…

P7740-[NOI2021]机器人游戏【dp,bitset】

正题 题目链接:https://www.luogu.com.cn/problem/P7740 题目描述 题目大意摸了 小 R 有 mmm&#xff08;1≤m≤10001 \le m \le 10001≤m≤1000&#xff09;个机器人和 mmm 张纸带&#xff0c;第 iii&#xff08;1≤i≤m1 \le i \le m1≤i≤m&#xff09;个机器人负责对第 …

CodeForces:54

文章目录前言CF54A PresentsDescription\text{Description}DescriptionSolution\text{Solution}SolutionCF54B Cutting Jigsaw PuzzleDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF54C First Digit LawDescription\text{Desc…

[NOIP2016 提高组] 愤怒的小鸟

[NOIP2016 提高组] 愤怒的小鸟 题意&#xff1a; 有n只猪&#xff0c;给出猪的坐标(xi,yi),问最少用几个形如 yax^2bx 的曲线可以保证所有猪在曲线上&#xff0c;满足a<0,a,b为实数 n<18, 题解&#xff1a; 两个方法&#xff1a;爆搜或者状压dp 状压dp 看n<18也…

P5208-[WC2019] I 君的商店【交互,二分】

正题 题目链接:https://www.luogu.com.cn/problem/P5208 题目大意 有一个长度为nnn的010101序列aaa&#xff0c;你知道里面有奇数个111还是偶数个111。你每次可以选择两个下标集合S/TS/TS/T询问集合SSS和集合TTT位置的数字和哪个更大。 交互库只会告诉你S≤TS\leq TS≤T或者…

模板:后缀数组(SA)

文章目录前言解析后缀排序优化1&#xff1a;基数排序优化2&#xff1a;简化第一次排序优化3&#xff1a;提前break完整代码LCP与height所谓后缀数组&#xff0c;就是存储后缀的数组 &#xff08;逃&#xff09; 前言 为什么一个算法&#xff0c;如此难以理解却依然是成为一个…

P3959 [NOIP2017 提高组] 宝藏

P3959 [NOIP2017 提高组] 宝藏 题意: 额题意不好说&#xff0c;就是n个点m个边&#xff0c;选定一个点为根节点&#xff0c;构造一个最小生成树&#xff0c;边的权值为该该边起点到根节点之间的点的数量K&#xff08;不含根节点&#xff09; * 道路长度 1<n<12 0<m&…

如何在ASP.NET Core程序启动时运行异步任务(3)

原文&#xff1a;Running async tasks on app startup in ASP.NET Core (Part 3)作者&#xff1a;Andrew Lock译者&#xff1a;Lamond Lu之前我写了两篇有关在ASP.NET Core中运行异步任务的博文&#xff0c;本篇博文是对之前两篇博文中演示示例和实现方法的简短跟进。你可以通过…

CF1140G-Double Tree【最短路,矩阵乘法,树上倍增】

正题 题目链接:https://www.luogu.com.cn/problem/CF1140G 题目大意 给出一个nnn个点的树TTT&#xff0c;然后复制一份T′TT′&#xff0c;每个TTT中的点iii向T′TT′中的点iii都有连边构成一张图。 图上所有权值各不相同&#xff0c;现在qqq次询问图上两点的最短路。 1≤n≤…

数论六之计算几何——An Easy Problem,Ancient Berland Circus,Open-air shopping malls

可检验模板正确度An Easy Problem?!Ancient Berland CircusOpen-air shopping mallsAn Easy Problem?! problem 就是大讨论 #include <cmath> #include <cstdio> #include <iostream> using namespace std; #define eps 1e-6struct vec {double x, y;ve…

CodeForces:12271261(div1)1262(div2)

文章目录前言CF1227A Math ProblemDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF1227B BoxDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF1227C MessyDescription\text{Des…

【NET CORE微服务一条龙应用】应用部署

简介本章主要介绍https://github.com/q315523275/FamilyBucket上微服务一条龙应用&#xff0c;在实际使用中的应用部署&#xff0c;以原始方式部署非docker部署应用主要包括&#xff1a;1、网关应用部署2、授权认证应用部署3、配置中心查询服务端应用部署4、综合管理应用部署5、…

牛客网区间dp练习

NC13230 合并回文子串 NC16129 小小粉刷匠 NC19909 [CQOI2007]涂色PAINT NC19997 [HAOI2016]字符合并 NC20238 [SCOI2003]字符串折叠 NC20252 [SCOI2007]压缩 NC20312 [SDOI2008]SUE的小球 POJ3042 Grazing on the Run

CF516D-Drazil and Morning Exercise【树上差分,倍增】

正题 题目链接:https://www.luogu.com.cn/problem/CF516D 题目大意 给出一棵nnn个点的树&#xff0c;定义f(x)f(x)f(x)表示距离点xxx最远的点的距离&#xff0c;qqq次询问给出一个kkk&#xff0c;要求一个最大的连通块满足连通块中所有点的f(x)f(x)f(x)最大最小差值不能超过k…

容斥问卷调查反馈——Co-prime,Character Encoding,Tree and Constraints,「2017 山东一轮集训 Day7」逆序对

文章目录Co-primesourcesolutioncodeCharacter EncodingsourcesolutioncodeTree and Constraintssourcesolutioncode「2017 山东一轮集训 Day7」逆序对sourcesolutioncodeCo-prime source TTT组数据&#xff0c;给出&#x1d43f;,&#x1d445;,&#x1d441;&#x1d43f;, …