[赛记] 暑假集训CSP提高模拟27
最后一场了,还是写写吧;
线性只因 40pts
赛时把与看成或了,最后才发现,结果我的神奇代码交上去得了40pts。。。
从高位到低位依次考虑,若这一位是1的数大于m则统计并删除其它的数;
否则直接跳过;
点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
int n, m;
int a[5000005];
int ans;
bool vis[5000005];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
int c = 0, o = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 30; i >= 0; i--) {
int sum = 0;
for (int j = 1; j <= n; j++) {
if (a[j] & (1 << i) && !vis[j]) sum++;
}
if (sum >= m) {
ans += (1 << i);
for (int j = 1; j <= n; j++) {
if (!(a[j] & (1 << i))) vis[j] = true;
}
}
}
cout << ans;
return 0;
}
金箱子 0pts
一道期望DP;
期望是可加的;
那么我们每增加一个钱数 $ a $,设以前的钱数为 $ x $,则我们新的要求的期望为 $ (x + a)^k = \sum_{i = 0}^{k} C_k^i \times x^i \times a^{k - i} $;
所以设 $ f[i][j] $ 表示前 $ i $ 个数,维护的是 $ x^j $ 的期望,依次递推维护 $ x^0 $ 到 $ x^k $ 的期望即可;
时间复杂度:$ O(nk^2) $;
点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
const long long mod = 998244353;
int n, k;
long long ans;
long long f[10005][105];
long long pa[10005], pb[10005];
long long ksm(long long a, long long b) {
long long ans = 1;
while(b) {
if (b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
long long fac[10005], fav[10005];
long long C(long long n, long long m) {
if (m == 0) return 1;
if (m > n) return 0;
if (m == n) return 1;
if (n == 0) return 0;
return fac[n] * fav[m] % mod * fav[n - m] % mod;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> k;
fac[0] = 1;
fav[0] = 1;
for (int i = 1; i <= 10000; i++) {
fac[i] = fac[i - 1] * i % mod;
fav[i] = ksm(fac[i], mod - 2);
}
f[0][0] = 1;
long long p, a, b;
for (int i = 1; i <= n; i++) {
cin >> p >> a >> b;
for (int j = 0; j <= k; j++) {
pa[j] = ksm(a, j);
pb[j] = ksm(b, j);
}
for (int j = 0; j <= k; j++) {
for (int x = 0; x <= j; x++) {
f[i][j] = (f[i][j] + C(j, x) * f[i - 1][x] % mod * (p * pa[j - x] % mod + ((1 - p) * pb[j - x] + mod) % mod + mod) % mod) % mod;
}
}
}
cout << f[n][k];
return 0;
}