目录
C - And and Pair(二项式定理)
思路
考虑枚举每一个 i i i,求满足条件的 j j j,容易发现,当 i i i确定时,令 i i i的二进制位从高位到低位第一个1往后0的数量为 x x x,则满足条件的 j j j为 2 x 2^x 2x。
由于和 i i i最高位的1有关,那么考虑枚举最高位为 b b b的所有 i i i。
假设原串在 b b b位之后1的数量为 y y y,0的数量为 x x x,那么最高位为 b b b的 i i i的数量为 2 y 2^y 2y,那么除了最高位之外还有 z z z个1的 i i i的数量为 C y z C_y^z Cyz,这些 i i i对应的 j j j的数量都为 2 x + ( y − z ) 2^{x+(y-z)} 2x+(y−z)( 0 ≤ z ≤ y 0 \le z \le y 0≤z≤y)
于是,以第 b b b位为最高位的 i i i对应的方案总数为
2 x ( C y 0 2 y + C y 1 2 y − 1 + . . . + C y y 2 0 ) = 2 x ( 1 + 2 ) y = 2 x 3 y 2^x(C_y^02^y+C_y^12^{y-1}+...+C_y^y2^0)=2^x(1+2)^y=2^x3^y 2x(Cy02y+Cy12y−1+...+Cyy20)=2x(1+2)y=2x3y
所以从后往前枚举一遍就可以啦
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
const int mod = 1000000007;
int n;
char s[N];
int qpow(int a, int b)
{
int res = 1;
while(b)
{
if (b & 1) res = 1LL * res * a % mod;
a = 1LL * a * a % mod;
b >>= 1;
}
return res;
}
int main()
{
int _;
scanf("%d", &_);
while (_ --)
{
scanf("%s", s + 1);
n = strlen(s + 1);
int c1 = 0, c0 = 0;
int ans = 0;
for (int i = n; i >= 1<

博客围绕多个算法题展开,包括C - And and Pair(二项式定理)、E - Bob’s Problem(简单图论)等。针对每个题目给出思路,如C题通过枚举最高位计算方案总数,E题用并查集维护图的连通性等,还附上对应代码。
最低0.47元/天 解锁文章
1248

被折叠的 条评论
为什么被折叠?



